我知道对于高数据使用率的实时多人游戏通常建议使用UDP。
大多数文章都是有用的,并且由于互联网上传输的所有数据中约80%是TCP,因此必须对TCP进行很多优化。
这让我感到奇怪:UDP在速度和延迟方面是否仍然优越?最近的TCP优化是否可以使TCP的性能优于UDP?
我知道对于高数据使用率的实时多人游戏通常建议使用UDP。
大多数文章都是有用的,并且由于互联网上传输的所有数据中约80%是TCP,因此必须对TCP进行很多优化。
这让我感到奇怪:UDP在速度和延迟方面是否仍然优越?最近的TCP优化是否可以使TCP的性能优于UDP?
Answers:
不,由于这两种协议的原理,UDP在性能延迟方面仍然优越,并且始终会更快。
TCP创建一个抽象,所有网络数据包到达时,它们按照发送时的确切顺序到达。为了在有损信道上实现这种抽象,它必须实现重传和超时,这会浪费时间。如果您在TCP上发送了2个更新,而第一个更新的数据包丢失了,则您将看不到第二个更新,直到:
在TCP中完成此操作的速度无关紧要,因为使用UDP,您只需丢弃第一个更新,而现在就使用第二个更新的更新。与TCP不同,UDP不保证所有数据包都到达,也不保证它们按顺序到达。
这要求您发送正确类型的数据,并以可以接受丢失数据的方式设计通信。
如果您有每个数据包都必须到达的数据,并且游戏必须按照数据包的发送顺序处理这些数据包,则UDP不会更快。实际上,在这种情况下使用UDP可能会比较慢,因为您正在重建TCP并通过UDP来实现它,在这种情况下,您也可能会使用TCP。
编辑-添加一些其他信息以合并/解决一些评论:
通常,以太网上的丢包率非常低,但是一旦涉及WiFi或用户正在进行上传/下载,丢包率就会变得更高。假设我们有0.01%的完全均匀的数据包丢失(单向,不是往返)。在第一人称射击游戏中,客户端应该在发生任何事情时发送更新,例如,当鼠标光标转动播放器时(每秒发生20次)。他们还可以每帧或以固定间隔发送更新,即每秒更新60-120。由于这些更新是在不同的时间发送的,因此每次更新将/应该在一个数据包中发送它们。在一个16人游戏中,所有16个玩家每秒将这些20-120个数据包发送到服务器,从而导致每秒总共320-1920个数据包。由于我们的数据包丢失率为0.01%,我们希望每5.2-31.25秒丢失一个数据包。
在丢失的数据包之后,我们收到的每个数据包都会发送一个DupAck,在第三个DupAck之后,发送方将重新传输丢失的数据包。因此,TCP启动重新传输所需的时间为3个数据包,加上最后一个DupAck到达发送方所花费的时间。然后,我们需要等待重传到达,因此总共要等待3个数据包+ 1个往返延迟。在本地网络上,往返延迟通常为0-1毫秒,在互联网上为50-200毫秒。如果每秒发送120个数据包,通常在25毫秒内到达3个数据包,而如果每秒发送20个数据包,则在150毫秒内到达。
相反,使用UDP,我们在收到下一个数据包后会立即从丢失的数据包中恢复,因此,如果每秒发送120个数据包,则丢失8.3毫秒;如果每秒发送20个数据包,则丢失50毫秒。
使用TCP时,如果我们还需要考虑Nagle(如果开发人员忘记关闭发送合并功能,或者无法禁用延迟的ACK),避免网络拥塞或者如果数据包丢失严重到必须考虑多个因素的情况,则情况将变得更加混乱。数据包丢失(包括丢失的Ack和DupAck)。使用UDP,我们可以轻松编写更快的代码,因为我们根本不关心像TCP这样的优秀网络公民。
我们都同意TCP和UDP都是建立在IP之上的协议,不是吗?IP指定了如何在Internet上传递消息,但是与消息的结构,格式无关。这是TCP和UDP协议。它们使用IP属性,但是让程序员专注于消息交换,而不必担心网络通信的底层。那就太好了,因为直接在电线中处理模拟信号会很痛苦。
TCP提供了一组发送和接收消息的功能。它为自己将数据分为小包,并通过网络发送。所有我们要求是端口使用的网窝,我们要实际的邮件发送。同样,它是可靠的,这意味着如果在网络上丢失了某些数据包,则会对其进行检测,然后再次发送,以确保它们按照应该到达的顺序发送。
另一方面,UDP是面向用户控制的协议。当使用UDP发送数据报时,我们无法确定数据报是否会到达目的地(在这里我们的意思是数学确定性:当我们发送数据包时,它可能会到达,但我们不确定100%)。同样,当数据包丢失时,既不会被检测到也不会再次发送。
在这一点上,TCP似乎是解决我们所有问题的理想解决方案。它可靠,速度快,它通过跟踪到达的数据包和仍需要发送的数据包为我们解决了连接延迟。
但是,超越。UDP给我们带来的唯一好处就是它的速度,而这正是我们真正想要的一件事。UDP数据包的制作,校验和发送无需任何特殊控制,因为这就是UDP协议的工作方式。必须对TCP数据包进行精心设计,标记,校验和,并在到达时发送ACK通知发送方“数据包x在这里,继续前进”,并且当未发送此信号时,则意味着必须发送此数据包x再次。
我知道对于高数据使用率的实时多人游戏通常建议使用UDP。
是的,但不仅如此。UDP比TCP更受青睐,主要是因为它的高速性是处理高数据发送和管理的想法。假设这种视频游戏以确定性的步伐运行(服务器上发生的事情在网络上与网络延迟无关地完全复制到任何客户端上),而更新包丢失并且永远不会到达目的地,则会发生这种情况。TCP将重新发送该数据包,随后的数据包将由于未按顺序到达而被丢弃,然后在丢失的数据包之后重新发送。在这种情况下,UDP的容忍度更高:它不会在意此数据包,因为新的更新即将到来。不会呈现丢失的更新,而是根据所使用的集成方法和收到的最新更新来内插游戏物理。
当延迟足够高时,TCP会引起抖动,而UDP则不会:
<video style="min-width: 100% height: auto" autoplay="" preload="auto" loop="true"><source src="https://gafferongames.com/videos/deterministic_lockstep_tcp_250ms_5pc.mp4" type="video/mp4"><source src="http://173.255.195.190/cubes_deterministic_lockstep_tcp_250ms_5pc.webm" type="video/webm">Your browser does not support the video tag.</video>
这使我想知道UDP在速度和延迟方面是否仍然优越。
好吧,是的,而且会持续很长时间。您可以在此处阅读有关TCP vs UDP的更多信息。
TCP <-传输控制协议。用于控制传输。
TCP的创建是为了成为一个良好的外交网络公民。它致力于使网络成为每个人的良好体验,并乐意降低实现该目标的吞吐量。它通过增加延迟来适应环境。原因例如:
另外
尽管有这些,TCP还是为(总传输数据)/(总消耗时间)提供了最高的数字。只是它不会在您希望发生时准确发生。
UDP都不做这些。它会激发您的意志,只是您无法期望它每次都会被击中-目标入内时必须宣布“您已经很长时间没有射击了,为什么?”。仍然可以创建自己的自定义ACK数据包,将多个记录放入一个数据包中,等等。同样重要的是,控制NAT遍历。UDP最适合于低延迟需求的游戏。
您可以将RFC 768(UDP)的第一张图与RFCP 793(TCP)第15页的第一张图进行比较。
两者均显示“源端口”的16位,然后显示“目标端口”的16位。两者都显示16位的“校验和”。根据RFC 768,UDP的“校验和过程与TCP中使用的相同。”
UDP的长度封装了UDP的详细信息,而TCP的长度则是第15和16页上所述的“ 96位伪头”的一部分。
不要指望TCP能够胜过UDP。由于多种原因,这根本不可能发生。一种是TCP仅具有更多位。因此,如果设备能够有效地每秒处理一定数量的位,则它将允许的UDP数据包多于TCP数据包。
另一个原因是TCP的“三向握手”意味着发送方必须等待响应。此要求引入了UDP无法处理的其他开销。您的大多数Internet通信都是从某些UDP通信开始的,这是有原因的。基本DNS使用UDP,因为与TCP的“三路握手”过程相比,请求和响应可以用更少的步骤完成。TCP跟踪丢失数据包的功能相当令人兴奋,因为计算机可以简单地发出新请求,而不是试图让远程系统知道有未完成的先前请求。
考虑一下发生了什么。为了简化方案,在尝试发送状态更改时,您有两种选择(例如,您的玩家刚刚改变了方向,或者开了枪,或者其他玩家刚刚放了炸弹):
假设在此之前不需要进行任何更新,那么单个更新到达1对2的时间将不会有很大的不同。这是从服务器到客户端的一趟旅程。但是,您要说的不只是炸弹爆炸,而是试图不断传递迷宫中奔跑者的活动。对于UDP,每项操作都会在发生数据报时立即发送。对于TCP,仅当允许服务器发送时,每个操作才会以数据包的形式发送。怎么说允许发送?在TCP窗口中留出空间(假定延迟的确认处于活动状态),以便可以将消息放在网络上。如果没有,它必须等待来自客户端的确认,然后再发送。
多久太久?当多人第一人称射击游戏发展迅速时,它在90年代末和2000年代初大步前进时,低延迟连接并不常见。拨号调制解调器通常具有180ms的单向延迟。在发送另一个更新之前等待一会儿确认,这实际上使该时间增加了一倍至360ms,这很痛苦。即使是新手用户也绝对可以感觉到差异。当宽带连接出现时,它们使延迟降低了很多,但是当带宽短缺时(在某些地区经常出现),它仍然持续存在。因此,对于最低可能延迟的偏好仍然存在。
现代家庭连接和互连改变了这一点,以至于区域延迟(即使在一天中的拥挤时间)也都在15毫秒或更短的范围内。在大多数情况下,由于等待时间“足够低”,因此选择TCP而不是UDP是不可见的。但是,考虑到它作为低延迟协议的历史,仍然存在UDP优先于TCP的趋势。因此,就目前而言(可能还有一段时间),UDP将是实时通信的首选。
我知道通常建议将UDP用于具有高数据使用率的实时多人游戏,
在速度和延迟方面UDP是否仍然优越?最近的TCP优化是否可以使TCP的性能优于UDP?
您的假设是错误的。TCP和UDP的主要区别在于它们表示的模型(不可靠的数据报与有序的可靠虚拟流)。
它们在容量(“高数据使用量”)或吞吐量方面没有区别。TCP将推送与UDP一样多的数据,它将很容易使物理电缆饱和。
在存在丢包的情况下,两者的时延确实有所不同,但仅在这种情况下。否则,TCP的延迟与UDP一样低(给出或花费几十纳秒的时间,因为网络堆栈有更多的逻辑要做,但这是可以忽略的)。
标头大小略有不同,因此从技术上讲,必须在串行线上通过更多的字节才能使它通过线路,但是那一点也无关紧要。批量转帐才真正重要,然后相差约0.5%。大多数具有家庭DSL互联网访问权限的人都会通过ATM路由所有流量,这增加了10%以上的协议开销(5个控制字节表示48个字节的有效负载,加上部分帧),甚至没人注意到。
有些人在UDP之上建立可靠性。如果需要某种程度的可靠性,但是不需要严格的有序交付,则可能会带来很小的优势。但是,这种方法是否有意义仍然值得商,,而您为此付出了小小的代价却付出了高昂的代价。
如果您有从酒店WiFi或其他“怪异”地方连接的客户端,您会注意到,通常对TCP的总体支持要比对UDP的支持好得多。
游戏通常使用UDP并不是因为它在上述一种方式中具有优势-并非如此-或者不是因为通过无序实现可靠性就可以将抖动降低半毫秒,而是因为游戏(类似于IP电话)通常包含很多非常不稳定的数据,例如位置更新。
随着时间的流逝以及进入下一个数据报,这些易变的数据将被定期且迅速地淘汰。这意味着没有什么比没什么大不了的了,实际上您并不是太在乎100%可靠(或按顺序)。
假设网络数据包以稳定的速度运行,并且有频繁的更新进入(射击游戏,电话,视频聊天),则确认超时并重新发送数据包并没有多大意义,同时在等待重发数据包到达时冻结另一端的所有内容。那太令人不安了,也没有好处。
取而代之的是,您只考虑丢失的数据包并继续前进,从通过它的下一个数据包中获取数据,与此同时,尽您所能,隐藏用户丢失数据包的事实。插值法,推算法,就是您的名字。
请注意,丢包是正常情况。虽然IP通常是“相当可靠”的,但偶尔发生的数据包丢失可能会发生,并且将会发生。虽然丢包通常是很少见的(这里<1%),但这不是非凡的或理论上的事情,也不是什么东西被破坏的迹象。这是完全正常的。
例如,每个TCP批量传输都必然包含丢失的数据包(这是拥塞控制的工作方式)。
在高带宽的MPG中,您不必担心是否错过了一个数据包,从而获得425号怪物的位置和健康状况,因为您将在几分之一秒内得到另一个更新。这是一个示例,其中UDP使TCP看起来很愚蠢,以至于让您等待立即过时的数据。
在同一个游戏中,您希望补丁按设计原样显示。TCP已经内置了“如果失败,请告诉我”功能,以便于自动重试和验证失败。您可以在UDP中进行操作,但是为什么要重新创建该技术?
这是正在发生的事情的简单描述。
UDP-隔离大块O'data。
制作一个小包。
封装在IP中。
装运它。
TCP-隔离流O'data。
从流的前面制作一个数据包。
封装在IP中。
在TCP窗口中等待空间。
装运它。
继续重新运输,直到收到收据或超时。
留在“ TCP”窗口中,直到收到收据或超时。
运送只是意味着它是通过本地NIC完成的,仅此而已。
TCP接收接收既可以保证数据接收,又可以在窗口中释放下一个数据包的空间。
重新发送(稍微)会增加最终接收的可能性。
TCP数据包在另一侧重新组合为有序的数据流。UPD数据包作为不同的数据包接收。该协议不保留顺序。
TCP非常适合推送所需的数据和大量有序的数据。TCP提供持久性故障的通知。TCP通过节流管道自动节流(参考:窗口)。TCP进行了握手以减慢初始化速度。TCP在传输之前需要“连接”。
UDP只是将数据放在网络上,让您无需等待窗口和重新传输即可继续进行操作。不管丢失多少数据,UDP都会将数据全速注入阻塞的管道中。
我设计并编写了商用的UDP组播文件传输实用程序。我已经在IP堆栈上工作了。这些只是基础知识,没有详细说明。解释“套接字,MTU和其他有趣的玩具”超出了对该问题有用的范围。
Ps(我无法添加评论以回复评论)UDP也适合需要但不是必需的数据。前向纠错就是一个例子,很多不必要的但可取的数据包。
是否所有经过TCP优化的路由器都使TCP的性能优于UDP?
另一个问题是:“数据繁重”是否意味着您将频繁加载场景?
如果是,您可能需要密集发送大量数据(> 1k),其中TCP可能会更加高效,因为特别是在服务器端,NIC将提供相同的周期的各种卸载。用户空间应用程序可能会使用TCP进行大量写入,而在UDP中尝试发送超过MTU标头大小的字节会导致IP碎片和其他开销,从而降低性能
UDP或TCP(或任何其他变体)都不是绝对优越的,甚至在速度/延迟方面也没有。您必须根据应用程序的要求进行选择。为此,您应该比较每种协议提供的功能,以了解更多的功能意味着更多的开销。因此,如果目标是最小化延迟或最大化速度,那么您应该选择一种协议,使其具有尽可能少的功能,同时又保留满足您的需求所需的基本功能。
一般来说,UDP(用户数据报协议)提供最少的功能。这很简单,因为您发送数据时没有任何形式的接收/确认。
另一方面,TCP(传输控制协议)提供了可靠的连接通信所需的最多功能。TCP通信发送重复或更多的数据包,并用订购信息标记它们。在目的地接收到数据后,必须将ACK(确认)与丢失数据包的信息一起发送回去,以便原始发送方可以重新发送那些丢失的数据包。如果我没记错的话,即使是ACK数据包也可能需要确认以确保适当的可靠性。
对于Skype电话会议,确保以可靠的方式发送/接收所有视频和音频数据并不重要。如今,无论如何,UDP在减少数据包丢失方面做得很好。要知道的重要一点是,在UDP中绝对不能保证传输是否成功。对于电话会议中的音频/视频数据,UDP是一个合适的选择,因为我们更关心获取实时数据(即最新数据)。如果到处丢失一些数据包,则不会以戏剧性的方式中断通信。
但是,在电话会议中,人们可以发送IM(即时消息)或发送文件。在这些情况下,可靠性是确保文件和消息不被损坏或丢失的必要条件。对于IM,您可能不需要TCP提供的连接状态。诸如RUDP(可靠UDP)之类的中间协议可能就足够了。但是,对于文件,可能需要具有TCP提供的连接状态。
如果您有复杂的应用程序或需要优化通信,那么从UDP通信开始是有益的。之后,您可以在顶部添加所需的所有功能。这将为您提供对网络通信的最大控制。
如果您有一个不需要优化的简单应用程序,请考虑使用一种标准(UDP或TCP)来满足您的需求。这将使您可以继续处理更重要的事情。