UDP vs TCP,速度要快多less?
对于一般的协议消息交换,可以容忍一些丢包。 UDP over TCP有效多less?
UDP比TCP更快,原因很简单,因为它不存在允许连续数据包stream的确认数据包(ACK),而不是确认一组数据包的TCP,它使用TCP窗口大小和往返时间(RTT )。
有关更多信息,我build议简单,但很容易理解的Skullbox解释(TCP与UDP)
人们说,TCP给你的主要东西是可靠性。 但是这不是真的。 TCP给你的最重要的事情是拥塞控制:你可以在一个DSL链路上运行100个TCP连接,所有连接都将以最快的速度运行,因为它们都“感知”了可用带宽。 尝试使用100个不同的UDP应用程序,所有这些应用程序都尽可能快地推送数据包,并查看事情对您有多好。
在更大规模上,这种TCP行为就是阻止互联网进入“拥塞崩溃”状态。
倾向于向UDP推送应用程序的东西:
-
组传递语义:可以比TCP的点对点确认更有效地向一组人进行可靠的传递。
-
无序交付:在大量的应用程序中,只要你得到所有的数据,你不关心它到达什么样的顺序; 您可以通过接受无序块来减less应用程序级别的延迟。
-
不友善:在一个局域网派对上,只要你的networking更新尽可能快,你可能并不关心你的networking浏览器是否运行良好。
但即使你关心性能,你可能也不想用UDP:
-
现在你已经处于可靠的状态了,你可能做很多事情来实现可靠性可能会比TCP已经做的慢。
-
现在,您的networking不友好,可能会在共享环境中导致问题。
-
最重要的是,防火墙会阻止你。
您可以通过将多个TCP连接“中继”在一起来潜在地克服一些TCP性能和延迟问题; iSCSI可以解决局域网拥塞控制问题,但是你也可以通过这种方式来创build一个低延迟的“紧急”消息通道(TCP的“URGENT”行为完全被破坏了)。
在某些应用程序中,TCP比UDP更快(吞吐量更好)。
这是相对于MTU大小进行大量小写操作的情况。 例如,我读了一个实验,其中300字节的数据包stream通过以太网(1500字节MTU)发送, TCP比UDP快50% 。
原因是TCP会尝试缓冲数据并填充整个网段,从而更有效地利用可用带宽。
另一方面,UDP将数据包立即放在线路上,从而使拥有大量小数据包的networking拥塞。
你可能不应该使用UDP,除非你有一个非常具体的理由这样做。 尤其是因为通过禁用Naglealgorithm (例如,如果您正在传输实时传感器数据,而您并不担心小数据包的拥塞),您可以给TCP提供与UDP相同的延迟。
与损失宽容
你的意思是“有损失容忍”吗?
基本上,UDP不是“损失容忍”。 你可以发送100个数据包给别人,他们可能只得到95个数据包,有些可能是错误的顺序。
对于像videostream和多人游戏这样的事情来说,如果错过一个数据包比延迟所有其他数据包更好,那么这是明显的select
对于大多数其他事情来说,丢失或“重新排列”的数据包至关重要。 你必须写一些额外的代码才能在UDP之上运行,以便在错过时重试,并执行正确的命令。 这会在某些地方增加一点点的开销。
谢天谢地,一些非常聪明的人已经这样做了,他们称之为TCP。
想想这样:如果一个数据包丢失,你宁愿只是尽快得到下一个数据包,并继续(使用UDP),或者你真的需要丢失的数据(使用TCP)。 除非你处于边缘情况下,否则开销不会有影响。
哪个协议性能更好(就吞吐量而言) – UDP或TCP – 实际上取决于networking特性和networkingstream量。 例如,罗伯特·S·巴恩斯(Robert S. Barnes)指出了TCP性能更好的一种情况(小型写入)。 现在,考虑networking拥塞并且同时具有TCP和UDP通信量的情况。 networking中使用TCP的发送者会感觉到“拥塞”并降低发送速率。 但是,UDP没有任何拥塞避免或拥塞控制机制,使用UDP的发送方将继续以相同速率抽取数据。 逐渐地,TCP发送者将把发送速率降低到最低限度,如果UDP发送者有足够的数据通过networking发送,他们将占用大部分可用的带宽。 所以,在这种情况下,UDP发送者将获得更大的吞吐量,因为他们获得更大的networking带宽。 实际上,这是一个活跃的研究课题 – 如何在UDPstream量的情况下提高TCP吞吐量。 我知道,使用哪个TCP应用程序可以提高吞吐量的一种方法是打开多个TCP连接。 这样,即使每个TCP连接的吞吐量可能受到限制,所有TCP连接的吞吐量总和可能会大于使用UDP的应用程序的吞吐量。
每个TCP连接都需要在数据传输之前进行初始握手。 而且,TCP报头包含了用于不同信号和消息传递检测的大量开销。 对于消息交换,如果出现小的失败几率是可以接受的,那么UDP就足够了。 如果收据必须经过validation,TCP是您的最佳select。
@安德鲁 ,我不同意。 由于性能要求,UDP是某些应用的select。 一个典型的例子是video会议。 这种应用程序对TCP控制没有很好的响应。
要考虑的其他方面是如果你将需要多播。 如果是这样,请使用UDP。
如果你需要在两个甚至还没有交谈的IP之间通过networking快速发送消息,那么UDP至less要快3倍,通常要快5倍。
在我的经验中,UDP稍微快一些,但是不是太多。 不应该在性能上做出select,而应该在消息内容和压缩技术上进行select。
如果这是一个有消息交换的协议,那么我build议你使用TCP所带来的非常轻微的性能是值得的。 两个端点之间的连接会给你所需要的一切。 不要试图在UDP上制造你自己的可靠的双向协议,除非你真的对你正在做的事情充满信心。
请记住,TCP通常会在线路上保留多条消息。 如果你想在UDP中实现这一点,如果你想要可靠地做到这一点,你将会有相当多的工作。 你的解决scheme要么不那么可靠,不够快,要么工作量不可思议。 有有效的UDP应用程序,但如果你问这个问题你可能不是。
已经做了一些工作来让程序员得到两个世界的好处。
SCTP
它是一个独立的传输层协议,但它可以作为一个库提供UDP上的附加层。 通信的基本单位是一个消息(映射到一个或多个UDP数据包)。 有内置的拥塞控制。协议有旋钮和twiddle来打开
- 按顺序发送消息
- 使用用户定义的参数自动重发丢失的消息
如果这是您的特定应用程序所需的任何。
与此有关的一个问题是,build立连接是一个复杂的过程(因此过程缓慢)
其他类似的东西
一个更类似的专有实验的东西
这也试图改进TCP的三重握手,改变拥塞控制以更好地处理快速线路。
谈到“什么是更快” – 至less有两个不同的方面:吞吐量和延迟。
如果谈到吞吐量 –TCP的stream量控制(如其他答案中所提到的)是非常重要的,并且在UDP上做任何事情都是可以比较的,尽pipe可能会是一个大头痛(tm)。 因此,当你需要吞吐量时使用UDP,很less有资格成为一个好主意(除非你想获得不公平的TCP优势)。
但是,如果谈到延迟 – 整个事情是完全不同的。 而在没有丢包的情况下,TCP和UDP的行为非常相似(任何差异,如果有的话,是边际的) – 在丢包后,整个模式发生巨大的变化。
在任何数据包丢失后,TCP将等待至less200ms的重传(RFC6298的第2.4段每秒1秒,但是实际的现代实现往往会将其减less到200ms)。 而且,对于TCP,即使那些到达目标主机的数据包也不会被传送到你的应用程序,直到收到丢失的数据包(即整个通信被延迟了〜200ms) – 顺便说一句,这个效应,称为Head-线阻塞是所有可靠的有序stream固有的,无论是TCP还是可靠的+有序的UDP。 更糟糕的是,如果重传的数据包也丢失了,那么我们将会谈到约600ms的延迟(由于所谓的指数退避,第一次重传是200ms,第二次重传是200 * 2 = 400ms)。 如果我们的频道有1%的数据包丢失(按今天的标准来看并不差),而且我们每秒钟有20次更新的游戏 – 平均每8分钟就会有600毫秒的延迟。 600毫秒足以让你在一场快节奏的比赛中遇难 – 这对于游戏来说是相当糟糕的。 这些效果正是为什么gamedevs通常比TCP更喜欢UDP的原因。
但是,当使用UDP来减less延迟时,意识到仅仅使用“UDP”不足以获得实质性的延迟改进是非常重要的,这完全是关于如何使用UDP的。 特别是,RUDP库通常避免了“指数退避”,并使用更短的重传次数 – 如果它们被用作“可靠的有序”stream,它们仍然必须遭受行头阻塞(因此在双倍情况下数据包丢失,而不是那600毫秒,我们将得到大约1.5 * 2 * RTT – 或者一个相当不错的80ms RTT,它是一个〜250ms的延迟,这是一个改进,但仍然可以做得更好)。 另一方面,如果使用http://gafferongames.com/networked-physics/snapshot-compression/和/或http://ithare.com/udp-from-mog-perspective/#low-latency-中讨论的技术,; 压缩 ,有可能完全消除线头阻塞(因此,对于每秒20次更新的游戏的双包丢失,无论RTT如何,延迟将是100ms)。
作为一个方面说明 – 如果你碰巧只能访问TCP但没有UDP(例如在浏览器中,或者如果你的客户端支持阻止UDP的6-9%的丑陋防火墙之一) – 似乎有办法实现UDP-over-TCP而不会产生太多的延迟,请看这里: http : //ithare.com/almost-zero-additional-latency-udp-over-tcp/ (请务必阅读评论(!))。
在不考虑networking条件的情况下讨论TCP或UDP是毫无意义的。 如果两点之间的networking质量很高,UDP绝对比TCP快,但是在其他一些情况下,比如GPRSnetworking,TCP可能比UDP更快更可靠。
我只会说清楚。 TCP / UDP是两辆车在路上行驶。 假设交通标志和障碍是错误TCP关心交通标志,尊重周围的一切。 开车缓慢,因为可能发生在汽车上。 当UDP刚刚开车的时候,全速不尊重路牌。 没什么,疯狂的司机。 UDP没有错误恢复,如果有障碍,它只会与它相撞,然后继续。 虽然TCP确保所有的数据包都是完美的发送和接收,没有错误,所以,汽车只是通过障碍物而不会碰撞。 我希望这是你理解的一个很好的例子,为什么UDP是游戏的首选。 游戏需要速度。 TCP优先于下载,或下载的文件可能已损坏。
networking设置对于任何测量都是至关重要的。 如果您通过本地机器上的套接字或与世界的另一端进行通信,则会产生巨大的差异。
我想补充的三件事:
- 你可以在这里find关于TCP和UDP在游戏开发中非常好的文章。
- 此外, iperf ( jperf用GUI增强iperf)是一个非常好的工具,可以通过测量自己回答你的问题。
- 我在Python中实现了一个基准testing(见这个SO问题 )。 在平均10 ^ 6次迭代中,发送8个字节的差别对于UDP是大约1-2微秒。