TCP协议是否足以应付实时多人游戏?


57

过去,拨号/ ISDN /慢速宽带上的TCP连接导致游戏断断续续,因为单个丢包会导致重新同步。这意味着许多游戏开发人员必须在UDP之上实现自己的可靠性层,或者他们将UDP用于可能会被丢弃或乱序接收的消息,并将并行TCP连接用于必须可靠的信息。

鉴于现在普通用户的网络连接速度更快,FPS之类的实时游戏能否通过TCP连接提供良好的性能?


Answers:


36

我会说不。游戏对象的空间信息需要尽可能快,因此最好使用UDP,因为可靠性不是100%关键。即使在现代连接上,UDP仍然足够慢,以至于您必须对插值等做出一些特殊考虑。即使仅就传输的数据量而言,TCP也会为此增加大量开销。

但是,TCP对于非实时事物(例如多人协商,聊天消息,分数更新等)是完全可以接受的。


7
肖恩几乎可以赚钱了。如果偶然地您正在C#/。NET中开发游戏(您知道自己想做!),那么我发现Lidgren网络库(code.google.com/p/lidgren-library-network)很漂亮好的选择。如果需要,它甚至可以通过UDP提供有序的,可靠的消息传递。
Mike Strobel

2
混合使用TCP和UDP是不明智的。由于TCP执行流量控制的方式,可能导致数据包丢失。(来源:isoc.org/INET97/proceedings/F3/F3_1.HTM
Jason Kozak,2010年

4
同样重要的是要记住,在某些情况下,您的最终用户将坐在阻止UDP流量的ISP后面,或者设置了阻止UDP流量的路由器设置,或者在其他情况下使用UDP不太理想。在这些情况下,如果您的游戏可以支持它,那么可以使用TCP通信就非常方便。
查尔斯·埃利斯

UD的另一个+点是它自然地面向数据包,如果需要,您必须在TCP中模拟它(boilderplatecode),可悲的是Windows不支持更现代的协议(这很糟糕)
Quonux

11

由于Flash不支持UDP,因此通过查看多人Flash游戏,您可以很好地了解TCP / IP可以实现的功能,以及不能实现的功能。基本上,您可以创建实时游戏,只要它们不依赖快速的响应时间即可。几个例子:

http://www.xgenstudios.com/play/stickarena

http://everybodyedits.com/

如果您可以选择使用UDP,那么您确实应该使用UDP,但是遗憾的是,使用Flash时,您不会使用该选项。


8

这取决于。

像《魔兽世界》这样的游戏使用TCP进行通信,因为您可以通过使用TCP来规避许多问题。结果可能是更高的ping,但是对于许多游戏来说,这是可以接受的。即使使用UDP作为协议,也需要进行空间插值。


1
不只是ping。魔兽世界没有玩家与玩家的冲突是有原因的。做得好很难。WOW可以使用TCP,因为您所处的位置无关紧要。瞄准和攻击并不取决于怪物或敌方玩家的真实位置。如果您关心这些事情,那么TCP将会损害播放体验。
Nuoji

6

如果您的客户端/服务器体系结构是干净的,则传输层(几乎)无关紧要。

TCP有一些缺点,但是很容易加以弥补。

是的,TCP和大脑就是您所需要的。

如今,有了通用的网络设置(代理,防火墙等),UDP对除本地(阅读:LAN)游戏以外的所有游戏几乎都是无用的。


7
如果您不赞成,请发表评论。我们使用TCP,从未遇到任何问题。
安德烈亚斯(Andreas)2010年

3
在此,我看不到常见网络设置的相关性。防火墙通常只干扰托管服务器,但无论协议如何,防火墙都会干扰,而代理实际上增加了延迟或丢包的风险,这使UDP比在本地网络上有用得多。可以通过自己进行完整性检查来很大程度上避免UDP的缺点,但是您不能将功能从TCP中剔除以使其更快。
马克·托马斯

1
您需要提及Nagles。我总是忘了这是TCP有害的根本原因(Nagle的缓冲区在客户端/服务器上缓冲数据包,基本上是从游戏中“保留”它们并引入额外的延迟)。
bobobobo

如果需要考虑延迟,有几个原因为什么应该使用UDP而不是TCP。如果您不关心延迟和/或能够进行足够的客户端预测,那么TCP就足够了。就实时游戏而言。忘记TCP。
Nuoji

6

如果关闭Nagle的算法,则使用TCP代替UDP是完全可以接受

关闭Nagle后,您将拥有UDP的大部分速度,并且完全可以制作抽搐反应游戏。确实,我在Flash中使用TCP做了这样的游戏:

http://2dspacemmo.wildbunny.co.uk

希望有帮助!


先生,您的链接无法正常运行的应用程序。
工程师

链接完全烂了,先生。我得到了Apache服务器测试。
Gustavo Maciel

4

对于FPS游戏,我们始终使用UDP。尤其是当您要进行抽搐射击时,Ping很重要。


4

这取决于游戏的种类。

某些游戏(例如RTS)在TCP上的性能要好得多,并且通常始终使用TCP。

TCP的真正问题是,如果您丢失了数据包-即使是很小的数据包-连接也会“停滞”直到发生重传。操作系统无法将乱序数据传送到应用程序(这破坏了TCP的保证,但是TCP也没有显示应用程序框架的边界)。连接停顿意味着后来的数据随后到达。但是在(例如)FPS游戏中,过时的数据是无用的。

使用UDP,应用程序可以选择对迟到或乱序的数据进行处理。它可以(对于FPS之类的游戏通常确实如此)忽略旧数据,而仅获取最新数据。偶尔丢失的数据包根本不会延迟后续的数据包。如果延迟的数据包最终到达,则游戏可以忽略它。


请注意,您的实现将需要处理丢弃延迟数据包的方面,因为UDP会将其视为接收到的数据报。
Guvante 2014年

3

不要只接受一个直截了当的“我说的是或否,因为”我在这里键入答案,因为您可能要面对一些实际上不需要您面对的UDP问题。

这里没有其他答案说明证明这一点的明显方法。

拿一些简单的事实

  • 无论使用哪种协议,IP头都是20个字节。
  • UDP标头为4个字节
  • TCP标头为20个字节

因此,每次发送1字节的消息时,根据协议(假设还需要IP标头),实际上实际上已发送25字节或41字节。

资料来源:

我的建议

考虑需要客户机与服务器交互的情况,估计客户机的数量,然后根据两次之间实际发送的数据进行数学计算。

一个例子

可以说,我发送10条消息,每次更新在我的游戏中每次更新为1个字节,而我正在以60 fps的速度更新,因此我需要发送60 * 10 = 600字节/秒的实际消息数据+相关标头。

现在,根据游戏的不同,我可以将所有消息作为一条消息发送,因此来自TCP层的开销仅为40字节(实际上是UDP的开销为每秒20字节),而没有开销则意味着潜​​在的开销为600字节(因为我可能必须重新发送整个消息流)。

但是,如果至关重要的是每条消息在准备好发送的那一刻就立即发送,那么我就有600条消息(也是600字节)+ 40 * 600 =每秒24k的TCP开销或每秒约14k的UDP开销+ 600字节的消息数据。

再次,我们提出以下问题:这些消息有多重要,它们的频率如何?是否可以通过某种方式将它们分批处理以减少开销?

那只是基于一堆单字节消息,通常您会做一些非常不同的事情,但是如果不知道原始数据的发送方式,很难证明TCP是否比UDP更适合您的情况。

那么,行得通吗?

好吧,如果您具有典型的fps,并且位置很重要(以避免作弊或错误的决定),则需要知道您的网络流是可以实现的,但是32个播放器每个流来回传输24k +消息字节(因此768KB / s +消息)...大约是10mb / s的宽带线,仅用于每个标头,基于每帧通过服务器从每个客户端向所有其他客户端发送至少1条消息。

显然,您不会编码服务器和客户端以这种方式工作,并且在大多数情况下,消息大小很可能比每帧1字节大得多,并且频率可能比1字节少一些,因此在不了解真实世界的情况下很难说“这是我需要发送的数据”示例。

我的情况

在我的案例中,我曾打电话说这是一个合理的开销,但这是基于我如何构建消息流的,因此与某些设计相比,我没有太大的开销。

TCP可以正常工作,并且我具有可伸缩的MMO服务器和客户端框架,但是由于可以批量调用,因此不需要在帧或小包中流式传输大量数据。

对于其他人:TCP只是行不通,他们只能使用UDP,但必须接受它不会为他们提供保证(订购/到达保证)。

其他注意事项

许多编码不佳的游戏引擎会处理cpu主线程上的所有内容,因此cpu通常仅获得很少的时间来处理网络代码,因此,服务和客户端的良好实现完全是异步的,并且可能会推送和批量提取消息。

有一些不错的网络库,但是从这里可以看出,许多人似乎认为UDP是“更好”,首先考虑您自己的需求,而事实并非如此,而找到一个没有的库与同一个库中的UDP变体相比,您做事的方式可能会导致TCP设置编码不良(我只是说我已经看到了这一点,并且负载测试已经证明了这一点)。

首先为要发送的数据构建一个技术基础,然后对其进行测试,然后进行数学计算以进行扩展,最坏的情况是通过将其部署到云中并对其进行负载测试,并让50台计算机运行测试客户端以查看其是否可以处理您每场比赛最多32名玩家(或您可能有的任何限制)。


2

我不这么认为...数据传输非常频繁的游戏(在鼠标移动或按下鼠标时)应使用UDP。如果使用TCP,即使在LAN上也将滞后。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.