【网络同步】
1、UDP包大小限制 。
运营过程中,发现有部分玩家,经常出现游戏不一致异常结束。日志中发现,玩家的Frame包校验码不正确,就是说这个包是错的。这怎么可能呢?网上都说UDP保证包数据的正确,看来也不尽然。
后来咨询了各种资料,总结出问题: 是数据报太大,被分组,部分路由器组包错误。(最大可能)
我们不断缩小分组长度: 1400 – 1200 – 1000 – 576 byte。最终我们定在了internet标准MTU尺寸576 byte(包含IP包头和UDP包头)。这个问题就基本搞定了。
2、通过冗余加快处理速度。
丢包重发后延迟怎么办?
如果收到Frame 3时, 同时携带Frame 2, 那么即使之前的Frame 2即使丢了,也不需要重传,就可立刻补充——这就是冗余方案。
冗余是通过流量换速度。
做一套动态冗余算法,包含上行逻辑和下行逻辑,通过每个客户端的丢包状况来动态调整冗余倍数。
也有一些游戏,通过全冗余来做,就是在客户端还没收到ACK时,总是携带所有没有ACK的数据。
这种方式简单粗暴,但是会导致流量增长N倍,各有利弊。
(下行冗余的倍率图,平均在1.4倍左右。还是比较理想的。(图中纵轴10000表示无冗余))
3、UDP回发的坑
当服务器收到UDP包后,如何回发也不太简单, 这在TCP里简直不是事。
当收到到第一个UDP包,高兴的记下回发地址, 以为就可以一劳永逸往里面塞包回发,那真是大错特错。
说实话,我们开始就是这么做的,结果客户端动不动就收不到回包。
解决办法是:
服务器每次收到包就都记下回发地址,这样中间路由如何变化,都可以送回去。
真的解决了吗? 其实依然可能收不到,不过还好,客户端总是会发送数据到服务器,这样就又会在中间路由器中,建立了通路,所以,这个办法还是可行的。
4、网络不稳定时,TCP经常断开
运行过程中, 我们发现了个奇怪现象,在跨网用户中,
用户可以流畅的比赛,但是控制协议确频繁的断开。 导致最终比赛异常结束。
其他服务器也有类似情况,问题其实发生在TCP的拥塞退让机制,因为丢包较多嗲话,TCP可能会频繁断线。
咨询了一些大牛,建议我们重构TCP,当然还是被TCP复杂的特性吓退了。最终,我们决心淘汰Relay server的TCP协议,实现了最简单的可靠UDP: 等停协议。
改造后,不单连接更稳定了, 因为只侦听UDP端口,连部署也更加容易了。
一个丢包的例子,这种情况UDP工作正常,但TCP就容易断线。
5、
6、