用于一般协议消息交换,可以容忍一些丢包.UDP over TCP有多高效?
人们说TCP给你的主要是可靠性.但事实并非如此.TCP为您提供的最重要的事情是拥塞控制:您可以在DSL链路上运行100个TCP连接,所有这些连接都以最大速度运行,并且所有100个连接都是高效的,因为它们都"感知"了可用带宽.尝试使用100种不同的UDP应用程序,尽可能快地推送数据包,看看有多好用.
在更大规模上,这种TCP行为使得互联网不会被锁定为"拥塞崩溃".
倾向于将应用程序推向UDP的事情:
组交付语义:与TCP的点对点确认相比,可以更有效地向一组人提供可靠的交付.
无序交付:在许多应用程序中,只要您获得所有数据,您就不关心它到达的顺序; 您可以通过接受无序块来减少应用级延迟.
不友好:在局域网聚会上,只要您尽可能快地对网络进行更新,您可能并不关心您的网络浏览器是否运行良好.
但即使您关心性能,您可能也不想使用UDP:
您现在已经处于可靠性状态,并且您实现可靠性所做的许多事情最终可能比TCP已经做得慢.
现在你的网络不友好,这可能会导致共享环境出现问题.
最重要的是,防火墙会阻止你.
您可以通过将多个TCP连接"中继"在一起来克服一些TCP性能和延迟问题; iSCSI这样可以解决局域网上的拥塞控制问题,但您也可以创建一个低延迟的"紧急"消息通道(TCP的"紧急"行为完全被破坏).
在某些应用中,TCP比UDP更快(更好的吞吐量).
当进行大量相对于MTU大小的小写时,就是这种情况.例如,我读了一个实验,其中通过以太网(1500字节MTU)发送300字节数据包流,TCP比UDP快50%.
原因是TCP将尝试缓冲数据并填充整个网段,从而更有效地利用可用带宽.
另一方面,UDP立即将数据包放在线路上,从而使网络拥有大量小数据包.
您可能不应该使用UDP,除非您有非常具体的理由这样做.特别是因为您可以通过禁用Nagle算法为TCP提供与UDP相同的延迟(例如,如果您正在传输实时传感器数据,并且您不担心使用大量小数据包来拥塞网络).
UDP比TCP更快,原因很简单,因为它的不存在的确认包(ACK)允许连续的数据包流,而不是通过使用TCP窗口大小和往返时间计算的确认一组数据包的TCP(RTT) ).
有关更多信息,我建议使用简单但非常易于理解的Skullbox解释(TCP与UDP)
容忍损失
你的意思是"有损失容忍度"吗?
基本上,UDP不是"容忍损失".您可以向某人发送100个数据包,他们可能只会获得95个数据包,而某些数据包的顺序可能不正确.
对于像视频流和多人游戏这样的东西,最好错过一个数据包而不是延迟它背后的所有其他数据包,这是显而易见的选择
但对于大多数其他事情,丢失或"重新安排"的数据包至关重要.您必须编写一些额外的代码才能在UDP之上运行,以便在错过任何内容时重试,并强制执行正确的顺序.这会在某些地方增加一点开销.
值得庆幸的是,一些非常聪明的人已经做到了这一点,他们称之为TCP.
可以这样想:如果数据包丢失了,您是想更快地获取下一个数据包并继续(使用UDP),还是实际上需要丢失数据(使用TCP).除非你处于一个真正的边缘情况,否则开销无关紧要.
哪种协议在吞吐量方面表现更好(UDP或TCP) - 实际上取决于网络特性和网络流量.例如,Robert S. Barnes指出TCP表现更好(小型写入)的情况.现在,考虑一种网络拥塞并同时具有TCP和UDP流量的场景.网络中使用TCP的发送者将感知"拥塞"并降低其发送速率.但是,UDP没有任何拥塞避免或拥塞控制机制,并且使用UDP的发送者将继续以相同的速率泵入数据.渐渐地,TCP发送器会将其发送速率降至最低,如果UDP发送器有足够的数据通过网络发送,它们将占用大部分可用带宽.因此,在这种情况下,UDP发送器将具有更大的吞吐量,因为它们可以获得更大的网络带宽.实际上,这是一个活跃的研究课题 - 如何在存在UDP流量的情况下提高TCP吞吐量.我知道,使用哪些TCP应用程序可以提高吞吐量的一种方法是打开多个TCP连接.这样,即使每个TCP连接的吞吐量可能受限,但所有TCP连接的吞吐量总和可能大于使用UDP的应用程序的吞吐量.
在谈到"什么是更快"时 - 至少有两个非常不同的方面:吞吐量和延迟.
如果谈论吞吐量 - TCP的流量控制(如其他答案中所述)是非常重要的,并且在UDP上做任何可比的事情,尽管可能,但是会有大头痛(tm).结果 - 当您需要吞吐量时使用UDP ,很少有资格作为一个好主意(除非您想通过TCP获得不公平的优势).
但是,如果谈到延迟 - 整个事情就完全不同了.虽然在没有数据包丢失的情况下,TCP和UDP的行为非常相似(任何差异,如果有的话,都是边缘的) - 在数据包丢失后,整个模式会发生巨大变化.
在任何数据包丢失之后,TCP将等待重传至少200ms(RFC6298的每段2.4秒1秒,但实际的现代实现往往会将其减少到200ms).此外,使用TCP,甚至那些到达目的地主机的数据包 - 在收到丢失的数据包之前都不会被传送到您的应用程序(即,整个通信延迟了大约200ms) - 顺便说一句,这种效应称为Head-of -Line Blocking是所有可靠有序流所固有的,无论是TCP还是可靠+有序的UDP.更糟糕的是 - 如果重传的数据包也丢失了,那么我们将谈论约600ms的延迟(由于所谓的指数退避,第一次重传是200ms,第二次是200*2 = 400ms).如果我们的频道有1%的数据包丢失(按今天的标准来说还不错),而且我们的游戏每秒有20次更新 - 平均每8分钟会发生600毫秒的延迟.而600米足以让你在快节奏的游戏中被杀 - 嗯,这对游戏玩法来说非常糟糕.这些效果正是gamedevs通常更喜欢UDP over TCP的原因.
但是,当使用UDP来减少延迟时 - 重要的是要意识到仅仅"使用UDP"不足以获得实质性的延迟改进,这完全取决于你如何使用UDP.特别是,虽然RUDP库通常避免"指数退避"并使用较短的重新传输时间 - 如果它们被用作"可靠的有序"流,它们仍然必须遭受线头阻塞(因此在双重情况下)数据包丢失,而不是600毫秒,我们将获得约1.5*2*RTT - 或者相当好的80毫秒RTT,它是一个〜250毫秒的延迟,这是一个改进,但它仍然可以做得更好).另一方面,如果使用http://gafferongames.com/networked-physics/snapshot-compression/和/或http://ithare.com/udp-from-mog-perspective/#low-latency-中讨论的技术,压缩,可以完全消除线头阻塞(因此对于具有20次更新/秒的游戏的双包丢失,无论RTT如何,延迟将是100ms).
并且作为旁注 - 如果您碰巧只能访问TCP但没有UDP(例如在浏览器中,或者如果您的客户端是6-9%的丑陋防火墙阻止UDP之一) - 似乎有办法实现UDP-over-TCP而不会产生太多的延迟,请参见此处:http://ithare.com/almost-zero-additional-latency-udp-over-tcp/(确保同时阅读注释(!)).
每个TCP连接都需要在传输数据之前进行初始握手.此外,TCP报头包含大量用于不同信号和消息传递检测的开销.对于消息交换,如果可接受的可能性很小,则UDP可能就足够了.如果必须验证收据,TCP是您的最佳选择.
@Andrew,我不敢苟同.由于性能要求,UDP是某些应用程序的选择.一个典型的例子是视频会议.这种应用程序对TCP控制没有很好的响应.
需要考虑的其他方面是您是否需要多播.如果是这样,请使用UDP.
如果你需要在两个尚未通话的IP之间快速通过网络发送消息,那么UDP的速度至少要快3倍,通常要快5倍.
根据我的经验,UDP稍快一点,但不是很多.不应该选择性能,而应该选择消息内容和压缩技术.
如果它是一个带有消息交换的协议,我建议你使用TCP获得的非常轻微的性能是非常值得的.您将获得两个端点之间的连接,这些端点将为您提供所需的一切.不要尝试在UDP之上制作自己可靠的双向协议,除非你真的对你正在进行的工作充满信心.
我会说清楚. TCP/UDP是在路上行驶的两辆车.假设交通标志和障碍是错误TCP关心交通标志,尊重周围的一切.驾驶缓慢,因为汽车可能会发生某些事情.虽然UDP只是开车,全速不尊重街道标志.没什么,一个疯狂的司机.UDP没有错误恢复,如果有障碍,它只会与它发生碰撞然后继续.虽然TCP确保所有数据包都被完美地发送和接收,但没有错误,因此,汽车只是通过障碍物而不会发生碰撞.我希望这是一个很好的例子让你理解,为什么UDP在游戏中是首选.游戏需要速度. TCP在下载中有优先权,或者下载的文件可能已损坏.
请记住,TCP通常会在线路上保留多条消息.如果你想在UDP中实现它,如果你想要可靠地完成它,你将会有很多工作.您的解决方案要么不太可靠,要么不太快,要么工作量大得惊人.有效的UDP应用程序,但如果你问这个问题你可能不是.