首页 文章

为什么游戏开发人员在应用程序级别中避免使用TCP并使UDP可靠?

提问于
浏览
5

许多游戏开发者选择在 application level 中使用 UDP . 这不是TCP的用途吗?我创建了一个API,使用UDP和TCP数据包启用客户端 - 服务器通信 . 我应该在列表中添加Reliable UDP吗?为什么?如果我使用TCP有问题吗?

我只是想知道 RUDP 是否对TCP有任何好处,因此我可以选择是否添加RUDP支持 .

4 回答

  • 2

    简短回答:TCP没有针对延迟进行优化(根本没有);结果 - 它有几个属性是游戏的延迟杀手(尽管它们只在数据包丢失时才会发挥作用) . 特别是,对于快节奏的游戏来说,线头阻塞和指数退避往往非常烦人 .

    最容易受到延迟影响的是线头阻塞(也就是HOL阻塞):如果一个数据包丢失,同一个流中的所有后续数据包,即使它们到达通信的另一端,也不允许到达应用程序级别(哎哟!),直到丢失的数据包被重新传输(这将需要大约2 * RTT,即使对于每个大陆的服务器,也是大约100毫秒(=“在射击游戏中,你已经被杀死) )) .

    答案很长:

    这是一个复杂的主题,我们需要区分几个不同的场景:

    • 我们需要可靠的有序消息(或字节)流 . 在这种情况下,RUDP对TCP的好处,虽然存在,但是非常小(我们可以通过减少重传次数来消除 - 并消除指数退避,但这几乎就是这样) . 特别是,对于任何类型的可靠有序流(无论是TCP,RUDP还是其他任何流),线头阻塞仍然是不可避免的 .

    • 我们需要一个可靠但可能无序的消息传递 . 这可能允许避免HOL阻塞,但需要相当复杂的应用程序级处理 .

    • 我们根本不需要可靠性(=“火与忘记”) . 这种信息的一个主要例子是当我们需要显示一颗子弹时 - 如果我们没有立即显示它,没有必要在半秒后显示它,所以如果数据包没有成功 - 好吧,最好忽略它,而不是花费资源重新发送数据包 .

    • 我们需要最终同步的状态(但我们不关心经历所有中间状态);这是一个非常常见的模拟场景 . 这可以通过UDP实现(并且不会导致HOL阻塞惩罚) . 但是 - 通过不可靠的连接进行压缩并非易事,而且大多数游戏都必须进行压缩 . 幸运的是 - 这样的压缩是可行的(参见http://gafferongames.com/networked-physics/snapshot-compression/和/或http://ithare.com/udp-from-mog-perspective/#low-latency-compression进行讨论) . 如果实现这种方法(可以在完全不可靠的数据包之上完成) - 它将提供相对于TCP的非常显着的改进(它确实消除了HOL阻塞,所以我们谈论网络滴答顺序的延迟 - 这可以低至1 / 120sec~ = 8ms - 超过RTT的延迟,对于单个数据包丢失,这些至少为100ms) .

    旁注:

    实际上,可以通过TCP模拟UDP(消除TCP延迟) - 请参阅http://ithare.com/almost-zero-additional-latency-udp-over-tcp/ . 请注意,要使用它,上面的所有内容仍应手动完成 . 仍然没有神奇的子弹可以避免HOL阻塞可靠排序的流;相反 - 这种技术允许使几个TCP连接表现为"almost as if"它是不可靠但非阻塞的UDP .

  • 2

    问题出在 out-of-order packets 上 .

    在查看之后,我了解到问题是TCP想要占用所有收到的数据包,直到它们收到应用程序所期望的 in the order . 这对于一个合理规模的多人游戏的性能来说可能是相当不利的,你只关心 latest player positions 而不是几毫秒之前 .

    RUDP改变了这一切,只是从Unity状态提供了"most recent packet"作为Erik:

    Erik-Juhl @ Unity Technologies

    人们通过TCP选择UDP / RUDP的主要原因是TCP如何处理无序数据包 . 您可能只关心最近收到的数据包,并希望它一到达即可 . 在TCP中,如果您最近收到的数据包不是顺序的下一个数据包,则在收到其他所有数据包之前,TCP不会将其传递给您 . 如果您需要保证顺序和交付,那么只需使用TCP . 如果你需要保证顺序和交付加上得到最新的数据包一到达,然后使用RUDP . 告诉我更多......

  • -1

    如果我相信并接受 . 开发人员继续这一点,因此在UDP (called RUDP) 上开发了一些可靠性,使其有点模仿TCP . 但是,它并没有完全实现TCP功能(总体而言) .

    那个's why I'想参考文章Reliable UDP (RUDP): The Next Big Streaming Protocol?来回答你的问题:

    TCP有一组指令,可确保每个数据包都能到达其收件人 . 它与最基本形式的记录交付相当 . 然而,虽然最初看起来很明显“确保消息到达那里”在向其他人发送内容时至关重要,但还有一些必须注意的额外注意事项 . 如果使用TCP / IP的网络链接注意到数据包已经不按顺序到达,则TCP停止传输,丢弃任何来自无序数据包的数据,发送“返回错误的地方”消息,以及再次开始传输 . 如果你有世界上所有的时间,这很好 . 因此,为了将我的工资信息从我的公司转移给我,我坦白地不在乎这需要一微秒或一小时,我希望它做得对 . TCP非常棒 . 然而,在以视频为中心的服务模型中,存在如此多的数据,如果少数数据包不通过链路进行,则有时我宁愿跳过这些数据包并继续进行视频的整体流动 . 获取原始来源的每个细节 . 我们的大脑可以为我们设想跳过的视频位,只要它不会被生涩的音频和定格动画视频分散注意力 . 在这些情况下,显然可以选择只是及时地从链路的一端向另一端发送尽可能多的数据,而不管有多少准确通过 . 对于这种类型的应用,UDP是最佳的 . 如果一个数据包似乎没有到达,那么收件人会等待片刻以确定它是否到达 - 可能直到 Spectator 需要看到该视频块的那一刻 - 以及缓冲区是否达到了这一点丢失的数据包应该在哪里,然后它继续进行,应用程序跳过丢失数据的点,继续下一个数据包并保持视频的时基 . 你可能会看到一个闪烁或一些瑕疵,但这一刻几乎立刻过去了,你的大脑很可能会填补空白 . 如果在TCP下发生此错误,则可以花费3秒的TCP来重新协商序列以从缺失点重新启动,丢弃所有后续数据,必须将其重新排队以再次发送 . 只丢失一个数据包就可以重新发送TCP数据的整个“窗口” .


    许多游戏开发人员选择在应用程序级别使UDP可靠 . 这不是TCP的用途吗?

    如果您能够容忍两端处理数据的速度,那就没问题 .

    但是,在游戏中,这不行 . 你必须每秒多次传递视频帧(和音频等),对许多玩家来说也是如此(如果是多人游戏) . 这一切都需要更快的速度和更快的数据处理能力;而不是使用相对较慢的TCP . 即使一些数据包在中途丢失,应用程序也可以继续运行,因为大脑也会转移到下一个而不是考虑那些紧张情绪 .

    我创建了一个API,使用UDP和TCP数据包启用客户端 - 服务器通信 . 我应该在列表中添加Reliable UDP吗?为什么?如果我使用TCP有问题吗?

    这取决于您希望应用程序更好地响应 . 我建议你在列表中添加Reliable UDP .

    我已经提到了TCP的问题 .

    我只是想知道RUDP是否对TCP有任何好处,因此我可以选择是否添加RUDP支持 .

    由于开销低,速度快,我敢打赌可靠的UDP,而不是庞大的TCP - 用于开发此类应用程序(游戏) .

  • 5

    我对这些协议了解不多,但根据我目前的知识,TCP是一种面向连接的协议,而UDP是一种无连接协议 . UDP主要用于实时在线多人游戏,因为UDP更快,因为没有尝试错误恢复 . 在那些游戏中,使用UDP是因为可靠性并不是真正重要的 . TCP采取措施确保客户端接收所有发送的数据包,而UDP只发送它们而不检查它们是否已经发送接收 . 如果我错了请纠正我!

    参考:http://www.diffen.com/difference/TCP_vs_UDP

相关问题