游戏服务器应该选择TCP还是UDP?

5
我知道,我知道。这个问题已经被问了很多次。但是我花了一个小时在谷歌上搜索,没有找到我要找的内容,所以我会再次提出这个问题,并提及我的背景以及让我难以做出决定的因素: 我正在为一个游戏编写服务器,响应时间非常重要偶尔丢失数据包并不是问题
根据这个和作为服务器我大部分时间必须向许多不同的客户端发送相同的数据,显然的答案是UDP。
当我开始编写代码时,我遇到了这个:

在某些应用中,TCP比UDP更快(吞吐量更高)。 当进行大量小写操作相对于MTU大小时,就是这种情况。例如,我读到了一项实验,在以太网(1500字节MTU)上传送300字节数据包流时,TCP比UDP快50%。

在我的情况下,我发送的信息单元是<100字节,这意味着每个信息单元都适合单个UDP数据包(这对我来说非常愉快,因为我不必处理分段),而UDP似乎更容易为我的目的实现,因为我不必处理大量的单个连接,但我的首要任务是将时间最小化
client sends something to server

client receives response from server

如果TCP是更快的方式,我愿意选择它。 不幸的是,我找不到关于上述引用案例的更多信息,这就是为什么我在问:在我的情况下哪个协议会更快?

1个回答

7
UDP对于您的使用情况仍然更好。TCP和游戏的主要问题是当数据包丢失时会发生什么。在UDP中,这就是故事的结束;数据包被丢弃,生活继续进行,直到下一个数据包。而在TCP中,跨越TCP流的数据传输将停止,直到成功重传丢失的数据包,这意味着不仅接收方不能及时接收丢失的数据包,而且随后的数据包也会被延迟——很可能它们都会在重新发送丢失的数据包完成后立即一起接收。
TCP的另一个可能对您不利的特点是其自动带宽控制——即TCP将解释丢失的数据包为网络拥塞的指示,并在响应中降低其传输速率;在许多数据包丢失的情况下,可能将其降低到接近零的程度。如果原因确实是网络拥塞,那么这可能是有用的,但是由于瞬态网络错误(例如用户断开以太网电缆几秒钟),数据包也可能会丢失,您可能不想以这种方式处理这些问题;但是在TCP中您别无选择。
UDP的一个缺点是,通常需要特殊处理才能让传入的UDP数据包通过用户的防火墙,因为防火墙通常会默认配置为阻止传入的UDP数据包。对于动作游戏来说,这可能值得处理一下这个问题。
请注意,这不是严格的二选一选项;您可以编写支持TCP和UDP两种协议的游戏,并同时使用它们,或者让程序和/或用户决定使用哪种。这样,如果一种方法效果不好,您只需要使用另一种方法,而且实现起来所需的工作量只增加了一倍。 :)

在某些应用中,TCP比UDP更快(吞吐量更高)。当进行很多相对于MTU大小较小的写操作时,情况就是这样。例如,我读过一个实验,在以太网(1500字节MTU)上传递300字节数据包的流时,TCP比UDP快50%。

如果这对您造成了问题,您可以通过将多个消息放在一个更大的UDP数据包中来获得相同的效率提升。例如,您可以将3个100字节的数据包放在1个300字节的数据包中发送。(当然,您需要确保接收程序能够正确地解释这个更大的数据包)。无论如何,这就是TCP层在这里所做的所有工作;在发送数据包之前,尽可能多地将数据放入可用和适合的传出数据包中。

1
谢谢,这个答案非常有用! 您提到了将多个信息单元放入单个数据包中以增加速度的可能性,为什么这样更有效呢? 发送一个包含50个字节的UDP数据包是否需要与包含500个字节的数据包相同的努力?还是仅仅因为您只需要为所有数据包使用1个包头而不是每个数据包都需要1个包头,因此可以节省一些字节? - LastExceed
1
每个UDP数据包的带宽开销为52字节,其中包括UDP、IP和以太网数据包头(参考来源:https://dev59.com/4nI-5IYBdhLWcg3wc3-w#1846139),并且每个数据包在与其交互的每个设备上都需要花费一定数量的CPU周期(参见:http://www.tamos.net/~rhay/overhead/ip-packet-overhead.htm)。不知道这种开销是否会在您的应用程序中引起注意,但它肯定是非零的。 - Jeremy Friesner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接