AI智能
改变未来

网络游戏丢包问题浅解

第一部分

先介绍三种协议,分别是TCP、UDP、HTTP。

TCP是可靠的传输层协议,但是其端到端的连接比较耗服务器资源,而且一旦丢包就会重发,阻塞住后续的数据包,因而可能会产生一个较大的瞬时延迟。其中“长连接”指的是tcp socket,tcp socket是操作系统为tcp协议的实现(说白了就是操作系统为tcp提供的api)。据说魔兽世界据说是用TCP。可能因为魔兽世界的游戏设计能很好的隐藏延迟,TCP用起来更简单些。

UDP 是“不可靠”的,不会丢包重传,会导致ip分片从而丢包,数据包不会按序送达,只保证到达的包数据是完整的,它的好处就是,不会产生tcp丢包时的队列阻塞,数据报头较小,只有8个字节,是一个无连接协议。

HTTP:因为http不需要持续地保持连接,是一个无状态的连接(可以通过cookie来实现客户端状态的验证),不会产生tcp所产生的断线重连的问题,服务器也不需要维护过多的连接。缺点就是需要经常的进行tcp握手操作(不会影响玩家体验),而且由于http的无状态性,通常游戏数据需要实时保存,不过现在的内存数据库 nosql的兴起和计算机性能的提升,这块劣势已经不存在,而且越来越多的游戏都采用实时数据保存,防止游戏服务器宕机数据回档的风险。再一个就是服务器无法主动向客户端推送数据,导致在某些功能上会无法实现。由于http的无状态性,需要做心跳处理,基于http的游戏服务器可以横向扩展(每一个游戏服务器进程就是一个单纯的逻辑计算器),数据库架构设计的好的话,一个游戏服很容易实现1亿+的玩家同服的情况。(该段部分摘自https://www.zhihu.com/question/39849641/answer/83774680)

第二部分

对于网络游戏尤其是动作类游戏,采用纯TCP协议是不符合业务要求的,但是采用其他协议如UDP就涉及到丢包问题。这里介绍几种网络游戏使用的协议方式以及一些针对丢包的方法。

1、UDP+TCP

如用户登录类业务采用TCP,而玩家动作操作上传等使用UDP协议。

关于丢包检查,可以采用一个近似TCP的ack机制,可以给每个数据包都添加一个sequence ID,然后发送端就依次发送数据包,接收端收到数据包后就可以根据sequence ID来判断是否有丢包了。seqid肯定是唯一,并且是递增的。

接收端处理先发包后到的情况,比如seqid在前的包比seqid在后的包晚到,这种情况就属于乱序了,收到一个包时,和上一个确认收到的包比对一下seqid,如果不连续说明这个包是乱序的。此时就可以根据需求,或者实现超时重传,或者直接跳过,因为有的同步消息不需要可靠的连接,比如位置同步信息偶尔丢一两个也没问题。网络路径的动态变化导致肯定会出现乱序的情况出现,因为我让:消息id的编号是连续递增的,而且每个消息包的序列号是唯一的,如:0、1、2、3、4,所以一旦有乱序,接收端可以察觉到(收到了0、1、3,你能知道 2 没有收到)。

如何应对乱序,取决与你的游戏设计以及你的同步策略设计。如果不要求绝对精准(能够replay重放的级别),那么直接使用id最新的包插值即可(不管2,直接处理3,2收到以后根据需求缓存或者丢弃)。但是如果你的同步要求非常严格,当你收到了3时,2还没有收到,你的客户端只好等2收到了再做同步,客户端的状态就会卡在1上,或者你的游戏逻辑允许根据1的状态预测插值。

总之乱序是网络的特性,如果你的游戏对同步的精度要求不高,你可以忽略它,如果要求精度很高(客户端精确的还原状态)你是不能忽略它的。

关于同步的体验,有一种思路大体是这样,你可以强制让客户端比服务端延迟个100~200毫秒,这个概念类似视频的缓冲,如果你看一个高清视频但是网络不够好经常卡,暂停等一下,让缓冲条多走一截,再播放就能得到流畅的体验。游戏也是一样的,你让客户端的update比服务器迟150ms,但是网络收包还是正常执行,那么,只要不出现150ms以上的延迟,同步就始终是精准而流畅的。

2、reliable udp(如UDT、KCP)

Reliable UDP(可靠的UDP)是一套服务品质的增强,比如拥挤控制调整,数据重传,薄化服务器算法等,这些增强可以提高服务器在数据包丢失和网络拥挤的条件下向RTP客户表现品质良好的RTP流的能力。Reliable UDP’的拥挤控制机制使系统在没有影响协议的实时本质的情况下,在行为上具备TCP协议的友好方式。

为了在英特网上处理好TCP网络流量,Reliable UDP使用数据重传和拥挤控制算法,与TCP协议采取的算法类似。另外,这些算法是经过时间考验的,可以很好地利用现有带宽。

Relibable UDP包括如下特性:

  • 客户端对服务器发出的数据包进行回应
  • 对窗口缓冲和拥挤进行控制,使服务器不超过当前可用的带宽。
  • 发生丢包时,服务器向客户重新发送数据
  • 比实时流更快的缓冲机制,称为“overbuffering”

客户端是否使用Reliable UDP取决于客户端发出的RTSP((Real-TimeStream Protocol )是一种基于文本的应用层协议) SETUP请求中的内容。

下图显示的是Reliable UDP应答包的格式。

3、http+udp

这种相对保守一些,逻辑相关的使用http协议,保证游戏逻辑不会出通讯上的问题,推送类的使用udp,比如聊天,世界公告等等,这些就算你的udp协议写的烂,也不会产生严重问题。如果实时性要求非常高的战斗功能,请使用udp。

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 网络游戏丢包问题浅解