处理实时游戏中的网络丢包 - TCP 和 UDP

Posted

技术标签:

【中文标题】处理实时游戏中的网络丢包 - TCP 和 UDP【英文标题】:Dealing with network packet loss in realtime games - TCP and UDP 【发布时间】:2015-03-31 20:14:00 【问题描述】:

为我的第一个网络游戏阅读了很多关于此的内容,我了解 TCP v UDP 的保证交付与交付时间的核心区别。我还阅读了完全相反的观点,即实时游戏应该使用 UDP 还是 TCP! ;)

关于丢包问题的处理方法,无人问津。

TCP :阅读一篇使用 TCP 的文章,了解 FPS 建议仅使用 TCP。使用 TCP 客户端输入的权威服务器将如何处理数据包丢失和突然的史诗般的延迟峰值?游戏是否只​​是暂停片刻,然后从中断的地方重新开始? TCP 数据包丢失是不是非常少见,以至于实际上并不是什么大问题,而且基于 TCP 的 FPS 实际上运行良好?

UDP:另一篇文章建议只使用 UDP。显然,像“手榴弹投掷”这样的一次性 UDP 事件不够可靠,因为它们有时不会触发。您是否必须手动实现消息接收、重新发送协议?还是其他解决方案?

我的游戏是一个基于滴答的权威服务器,从服务器到客户端的更新时间为 1/10 秒,本地模拟使事情看起来更具响应性,尽管这个问题适用于更多的应用程序。

【问题讨论】:

【参考方案1】:

我做了一个实时电视编辑系统。所有实时通信都是通过 UDP 进行的,但非实时使用 TCP,因为它更简单。使用 UDP,我们将每帧发送一个状态包。例如start video in 100 frames, 99,98,…3,2,1,0,-1,-2,-3 因此,即使在 -3 之前没有消息通过,接收者也会从第 4 帧开始(只是跳过前 3 帧),希望没人会注意到,并且知道这比从这里开始滞后要好。我们甚至添加了大约 +¼ 秒的倒计时(没人会注意到),这样几乎没有丢帧。

总而言之,我们每帧都发送相同的状态包。它包含有关过去、当前和未来事件的所有实时数据。

诀窍是保持这个数据集很小。因此,我们发送视频 ID、帧号、开始掩码和结束掩码,而不是发送播放按钮按下事件(这些事件的数量不限)。 (开始/停止掩码是帧号,如果开始掩码为正,停止掩码为负,则显示视频,在帧帧号处)。

现在我们需要能够在另一个视频期间或在视频停止后不久开始播放。所以我们考虑可以同时播放多少个连续的视频。我们需要一个插槽,但我们可以立即重用它们吗?如果我们按下了停止,那么直到那时才知道停止掩码,然后重新使用插槽将视频停止。好吧,这个视频不会有空档,所以我们应该停止它。所以是的,只要我们使用唯一的 ID,我们就可以立即重用该插槽。

其他提示:不要发送 +1 事件,而是发送当前总数。如果两个玩家必须更新某个总数,那么每个人都应该有自己的总数,在使用时将所有总数相加,但永远不要编辑其他人的总数。

【讨论】:

以上是关于处理实时游戏中的网络丢包 - TCP 和 UDP的主要内容,如果未能解决你的问题,请参考以下文章

网络协议趣谈TCP协议连接和状态

TCP和UDP的区别

前端面试题-TCP和UDP的区别

tcp和udp的区别

【web】TCP和UDP、HTTP的区别

TCP与UDP在socket编程中的区别