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

时间:2016-09-05 03:31:46

标签: networking tcp udp rudp

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

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

4 个答案:

答案 0 :(得分:6)

问题在于无序数据包

在查看之后,我了解到问题是TCP想要占用所有收到的数据包,直到它们按照应用程序期望的顺序接收。对于一个规模相当大的多人游戏来说,这可能会对你的表现产生相当大的影响,你只关心最新的玩家位置,而不是几毫秒之前。

RUDP 改变了这一切,只是提供了来自Unity的Erik的“最新数据包”:

Erik-Juhl @ Unity Technologies

  

人们通过TCP选择UDP / RUDP的主要原因是TCP如何处理无序数据包。您可能只关心最近收到的数据包,并希望它一到达即可。在TCP中,如果您最近收到的数据包不是顺序的下一个数据包,则在收到其他所有数据包之前,TCP不会将其传递给您。

     

如果您需要保证序列和投放,请使用 TCP 如果您需要保证顺序和交付,并在收到后立即获取最新的数据包,请使用RUDP Tell me more...

答案 1 :(得分:4)

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

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

答案很长:

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

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

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

  3. 我们根本不需要可靠性(="火灾和遗忘")。这种信息的一个主要例子是当我们需要显示子弹时 - 如果我们没有立即显示它,则不需要在半秒后显示它,所以如果数据包没有制作它 - 好吧,最好忽略它,而不是花费资源重新发送数据包。

  4. 我们需要最终同步的状态(但我们不关心经历所有中间状态);这是一个非常常见的模拟场景。这可以通过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)。

  5. 旁注:

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

答案 2 :(得分:3)

如果我直接说UDP比用于此类应用程序的TCP更快,比TCP更快;你不会相信和接受。开发人员继续这一点,因此在UDP (称为RUDP) 上开发了一些可靠性,使其有点模仿TCP。但是,它并没有完全实现TCP功能(总体而言)。

这就是为什么我想参考文章Reliable UDP (RUDP): The Next Big Streaming Protocol?来回答你的问题:

  

TCP有一组指令,可确保每个数据包   得到它的收件人。它与其记录的交付量相当   最基本的形式。然而,虽然一开始似乎很明显“制作   确保消息到达那里“在发送内容时至关重要   其他人,必须注意一些额外的考虑因素。   如果使用TCP / IP的网络链接通知数据包已到达   顺序,然后TCP停止传输,丢弃任何东西   无序数据包前进,发送“返回到它去的地方   错误的“消息,然后再次开始传输。

     

如果你有世界上所有的时间,这很好。因此对于   我坦率地说,将我的工资信息从我的公司转移给我   如果这需要一微秒或一小时,我不在乎,我希望它完成   对。 TCP非常棒。

     

然而,在以视频为中心的服务模式中,有这么多   数据,如果一些数据包没有通过链接   我宁愿跳过这些数据包并继续使用的情况   视频的整体流程比得到原始的每一个细节   资源。我们的大脑可以为我们想象跳过的视频位   只要它不会被生涩的音频和定格动画视频分心。   这些情况下,可以选择发送尽可能多的数据   无论如何,及时联系到另一端的一端   多少准确通过,显然是可取的。就是这样   UDP最佳的应用程序类型。如果一个数据包似乎没有   到了,然后收件人等了一会儿,看看是不是   到达 - 可能直到观众需要的那一刻   看到那个视频块 - 如果缓冲区到达那里的位置   丢失的数据包应该是,然后它只是继续,和   应用程序跳过丢失数据所在的点,继续执行   下一个数据包并保持视频的时基。你可以   看到一个闪烁或一些神器,但这一刻几乎消失了   立刻,你的大脑很可能会填补空白。

     

如果在TCP下发生此错误,则可以通过TCP upward of 3 seconds重新协商序列以从缺失中重新启动   点,丢弃必须重新排队的所有后续数据   再发一次。只丢失一个数据包可能会导致整个“窗口”   要重新发送的TCP数据。

  

许多游戏开发者选择在应用程序中使UDP可靠   水平。这不是TCP的用途吗?

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

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

  

我制作了一个API,可以使用UDP和UDP进行客户端 - 服务器通信   TCP数据包。我应该在列表中添加Reliable UDP吗?为什么?在那儿   如果我使用TCP会出现问题吗?

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

我已经提到了TCP的问题。

  

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

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

答案 3 :(得分:-1)

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

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