由于TCP保证了数据包的传递,因此可以被认为是“可靠的”,而UDP不保证任何内容,因此数据包可能会丢失。在应用程序中而不是通过TCP流使用UDP传输数据的优势是什么?在哪种情况下,UDP是更好的选择,为什么?
我假设UDP更快,因为它没有创建和维护流的开销,但是如果某些数据永远不会到达目的地,那不是无关紧要的吗?
由于TCP保证了数据包的传递,因此可以被认为是“可靠的”,而UDP不保证任何内容,因此数据包可能会丢失。在应用程序中而不是通过TCP流使用UDP传输数据的优势是什么?在哪种情况下,UDP是更好的选择,为什么?
我假设UDP更快,因为它没有创建和维护流的开销,但是如果某些数据永远不会到达目的地,那不是无关紧要的吗?
Answers:
这是我最喜欢的问题之一。UDP被误解了。
如果您确实希望快速获得对另一台服务器的简单答复,则UDP效果最佳。通常,您希望答案在一个响应包中,并且您准备实现自己的协议以提高可靠性或重新发送。DNS是此用例的完美描述。建立连接的成本太高了(但是,DNS确实也支持TCP模式)。
另一种情况是当您传递的数据可能会丢失,因为传入的新数据将替换先前的数据/状态。我想到了天气数据,视频流,股票报价服务(不用于实际交易)或游戏数据。
另一种情况是,当您管理大量状态时,由于操作系统无法处理那么多会话,因此您希望避免使用TCP。今天,这种情况很少见。实际上,现在可以使用用户级TCP堆栈,以便应用程序编写器可以对该TCP状态所需的资源进行更精细的控制。在2003年之前,UDP确实是该镇唯一的游戏。
另一种情况是多播流量。UDP可以组播到多个主机,而TCP根本不能这样做。
如果TCP数据包丢失,它将被重新发送。对于依赖于以特定顺序实时处理数据的应用程序而言,这并不方便。
示例包括视频流,尤其是VoIP(例如Skype)。但是,在这些情况下,丢包并不是什么大问题:我们的感觉并不完美,因此我们甚至可能不会注意到。这就是为什么这些类型的应用程序使用UDP而不是TCP。
UDP的“不可靠性”是形式主义。传输不是绝对保证的。实际上,它们几乎总是能够通过。超时后,它们不会被确认并重试。
协商TCP套接字和握手TCP数据包的开销很大。真的很大。没有明显的UDP开销。
最重要的是,您可以通过一些可靠的交付握手协议轻松地补充UDP,而这些握手开销要比TCP少。阅读此:http : //en.wikipedia.org/wiki/Reliable_User_Datagram_Protocol
UDP对于在发布-订阅类型的应用程序中广播信息很有用。IIRC,TIBCO大量使用UDP来通知状态更改。
UDP数据包可以很好地处理任何其他类型的单向“重要事件”或“记录”活动。您要发送通知而无需构造整个套接字。您不会期望各种听众有任何回应。
系统“心跳”或“我还活着”的消息也是一个不错的选择。错过一个不是危机。(连续)丢失六打。
我正在开发一种同时支持客户端和服务器之间的UDP(IP)和TCP / IP通信的产品。它始于15年前的IPX,并于13年前添加了IP支持。我们在3或4年前添加了TCP / IP支持。即将出现大胆猜测:UDP与TCP的代码比率可能约为80/20。该产品是数据库服务器,因此可靠性至关重要。我们必须处理其他答案中已经提到的UDP带来的所有问题(数据包丢失,数据包加倍,数据包顺序等)。几乎没有任何问题,但有时确实会发生,因此必须加以解决。支持UDP的好处是我们可以根据自己的使用情况对其进行一些自定义,并从中调整一些性能。
每个网络都会有所不同,但是UDP通信协议对我们来说通常更快一些。持怀疑态度的读者会正确地质疑我们是否正确实施了所有措施。另外,您对拥有2位数字代表的人有什么期望?不过,出于好奇,我现在才进行了测试。该测试读取了100万条记录(从某个表中选择*)。我将要返回的每个客户请求的记录数分别设置为1、10和100(每个协议运行三个测试)。该服务器距离100Mbit LAN仅两跳路程。这些数字似乎与过去的发现相吻合(在大多数情况下,UDP的速度提高了约5%)。此特定测试的总时间(以毫秒为单位)如下:
对于IP和TCP,传输的总数据量大致相同。UDP通信会产生额外的开销,因为我们拥有一些您可以免费使用TCP / IP获得的相同内容(校验和,序列号等)。例如,Wireshark显示对下一组记录的请求是UDP的80字节,TCP的84字节。
这里已经有很多好的答案,但是我想补充一个非常重要的因素以及摘要。UDP通过正确的调整可以实现更高的吞吐量,因为它不使用拥塞控制。TCP中的拥塞控制非常非常重要。它通过尝试估计连接的当前容量来控制连接的速率和吞吐量,以最大程度地减少网络拥塞。即使通过非常可靠的链路(例如在核心网络中)发送数据包,路由器的缓冲区大小也有限。这些缓冲区填满其容量,然后丢弃数据包,TCP通过缺少接收到的确认来通知此丢失,从而限制了连接速度以估算容量。TCP还采用了一种称为“ 慢启动”的方法,但是吞吐量(实际上是拥塞窗口))缓慢增加直到丢包,然后降低然后再次缓慢增加直到丢包等。这导致TCP吞吐量波动。下载大文件时,您可以清楚地看到这一点。
因为UDP不使用拥塞控制,所以它既可以更快,又可以减少延迟,因为UDP不会设法最大化缓冲区直到丢失点,即UDP数据包在缓冲区中花费的时间更少,并且延迟更短而到达那里。由于UDP不采用拥塞控制,而TCP则采用拥塞控制,因此它可以占用TCP到UDP流的容量。
UDP仍然容易受到拥塞和丢包的影响,因此您的应用程序必须准备好以某种方式处理这些复杂情况,可能使用重传或纠错码。
结果是UDP可以:
总之,只要您还实现适当的重传机制,UDP便可以用于TCP可以使用的每种类型的应用程序。UDP可以非常快,具有较少的延迟,不受连接拥塞的影响,可以传输固定大小的数据报,并且可以用于多播。
UDP确实具有较少的开销,并且适合执行诸如流传输实时数据(如音频或视频)之类的事情,或者在任何情况下如果数据丢失都可以。
对于这个问题,我知道最好的答案之一来自Hacker News的用户zAy0LfpBZLC8mAC。这个答案太好了,我将直接引用它。
TCP具有队列头阻止功能,因为它保证完整且有序的传递,因此,当数据包在传输过程中丢失时,它必须等待丢失的数据包的重新传输,而UDP在数据包到达时将其传递给应用程序,包括重复项,并且不能保证包到达所有包或到达包的顺序(它实际上是具有端口号并添加了(可选)有效载荷校验和的IP),但是对于电话来说(例如,通常在当丢失几毫秒的音频时根本不重要,但是延迟很烦人,因此您不必为重新传输而烦恼,只需丢弃所有重复项,就可以将重新排序的数据包按正确的顺序排序,以获得数百毫秒的抖动缓冲,并且如果数据包没有及时显示或根本没有显示,则将其跳过,可能在编解码器支持的地方进行插值。
另外,TCP的主要部分是流量控制,以确保获得尽可能多的吞吐量,但又不会使网络过载(这是多余的,因为过载的网络会丢弃您的数据包,这意味着您必须这样做重新传输(这会损害吞吐量)),UDP则没有任何内容-这对于电话等应用来说是有意义的,因为具有给定编解码器的电话需要一定的带宽,您不能“降低它”的速度,并且还需要额外的带宽不会使通话速度更快。
除了实时/低延迟应用程序外,UDP还可以用于非常小的事务(例如DNS查找),原因仅在于就延迟和带宽使用而言,UDP没有TCP连接建立和拆除开销。如果您的请求比典型的MTU小,并且响应也可能是,则您可以在一次往返中完成,而无需在服务器上保留任何状态,流控制也可以排序,而所有这些可能都不是特别有用用于此类用途。
然后,您当然可以使用UDP来构建自己的TCP替代品,但是如果不对网络动力学有深入的了解,这可能不是一个好主意,现代TCP算法非常复杂。
另外,我想应该提到的是,除了UDP和TCP外,还有SCTP和DCCP。当前唯一的问题是(IPv4)Internet充满了NAT网关,这使得在最终用户应用程序中无法使用UDP和TCP以外的协议。
UDP具有较低的开销,如上所述,它对于流传输诸如视频和音频之类的内容非常有用,最好丢掉一个数据包然后尝试重新发送并赶上。
TCP传输没有任何保证,仅应告知您套接字是否已断开连接,或者基本上是如果数据不会到达。否则它到达那里时就到达那里。
人们忘记的一个大事是udp是基于数据包的,而tcp是基于字节流的,因此不能保证您发送的“ tcp数据包”是在另一端显示的数据包,可以将其分解为尽可能多的数据包如路由器和堆栈所希望的。因此,您的软件具有将字节解析回可用数据块中的额外开销,这可能会花费相当多的开销。UDP可能会乱序,因此您必须对数据包编号,或者如果需要的话,可以使用其他某种机制对其进行重新排序。但是,如果您获得了该udp数据包,则该数据包将以所有相同的字节到达,并且顺序与原来的顺序相同,没有任何变化。因此,术语udp数据包有意义,而tcp数据包则不一定。TCP具有自己的重试和排序机制,对您的应用程序是隐藏的,
UDP在两端都更容易编写代码,基本上是因为您不必建立和维护点对点连接。我的问题通常是在什么情况下需要TCP开销?而且,如果您采取一些捷径,例如假设接收到的TCP“数据包”是已发送的完整数据包,那么您的状况更好吗?(如果您费心检查长度/内容,则可能会丢掉两个数据包)
关键问题与“在[TCP]上UDP是哪种情况更好”有关。
上面有很多很好的答案,但是缺少对运输不确定性对TCP性能的影响的任何正式,客观的评估。
随着移动应用程序的迅猛发展,以及随之而来的“偶发连接”或“偶发断开”的范例,在某些情况下,当难以建立连接时,TCP尝试维护连接的开销会导致强大的性能。 UDP及其“面向消息”的性质。
现在我还没有数学/研究/编号,但是我生产的应用程序使用UDP进行ACK / NAK和消息编号时比使用TCP时无法实现的可靠性更高,而当连接性普遍较差且旧TCP较差时,只是花时间,而我客户的钱只是在尝试联系。您可以在许多西方国家的地区和农村地区获得此服务。
在某些情况下(其他情况已强调),保证数据包的到达并不重要,因此使用UDP很好。在其他情况下,UDP比TCP更可取。
您想使用UDP而不是TCP的一种独特情况是,您通过另一种协议(例如,隧道,虚拟网络等)建立TCP隧道。如果在TCP之上通过TCP隧道传输,则每个拥塞控制都会相互干扰。因此,人们通常更喜欢在UDP(或其他一些无状态协议)上建立TCP隧道。请参阅TechRepublic文章:了解TCP之上的TCP:TCP隧道对端到端吞吐量和延迟的影响。
这并不总是很明确。但是,如果您需要保证数据包的传输没有丢失并且按正确的顺序进行传输,则可能需要TCP。
另一方面,UDP适用于在信息序列不太重要或数据可以放入单个数据包的情况下传输短信息包。
当您要将相同的信息广播给许多用户时,这也是合适的。
其他时候,当您发送排序的数据时比较合适,但是如果其中一些丢失了,则不必太担心(例如VOIP应用程序)。
有些协议更为复杂,因为所需的只是TCP的某些(但不是全部)功能,而不仅仅是UDP提供的功能。那是应用程序层必须实现附加功能的地方。在那些情况下,UDP也适用(例如,互联网广播,顺序很重要,但并非每个数据包都需要通过)。
可以/可以在何处使用的示例1)时间服务器向LAN上的一堆机器广播正确的时间。2)VOIP协议3)DNS查找4)请求LAN服务,例如您在哪里?5)网络广播6)和许多其他...
在Unix上,您可以键入grep udp / etc / services以获得今天实现的UDP协议列表...有数百种。
查看Steven的Unix网络编程的 22.4节 “何时使用UDP代替TCP”。
另外,请参阅有关SO 误解的其他SO答案,即UDP总是比TCP快。。
史蒂文的话可以总结如下:
在沿途丢失某些数据不会完全破坏正在传输的数据的情况下,您想使用基于TCP的UDP。它的许多用途都用于实时应用程序中,例如游戏(例如FPS),您不必总是知道每个给定时间每个玩家的位置,如果您在此过程中丢失了一些数据包,数据会正确地告诉您播放器的位置,以及实时视频流(一个损坏的帧不会破坏观看体验)。
当TCP可能工作时,我不太愿意建议UDP。问题是,如果由于某种原因TCP无法正常工作,因为连接太慢或太拥挤,那么更改应用程序以使用UDP不太可能有帮助。错误的连接对UDP也有害。TCP已经在减少拥塞方面做得非常好。
我能想到的唯一情况是广播协议需要UDP。在一个应用程序涉及两个已知主机的情况下,UDP可能仅会带来边际性能优势,同时会大大增加代码复杂性的成本。
仅当您真正知道自己在做什么时才使用UDP。UDP在当今极为罕见的情况下,但是试图将其粘贴到任何地方的(甚至非常有经验的)专家的数量似乎不成比例。也许他们喜欢自己实现错误处理和连接维护代码。
由于所谓的校验和烙印,应该期望现代网络接口卡的TCP更快。出乎意料的是,在快速的连接速度(例如1Gbps)下,计算校验和对于CPU来说将是一个很大的负担,因此它会分流到可识别TCP数据包以进行标记的NIC硬件上,并且不会为您提供相同的服务。
UDP非常适合VoIP寻址,而不必考虑其可靠性,而必须发送数据包。视频聊天是UDP的一个示例(您可以在任何视频聊天期间通过Wireshark网络捕获对其进行检查)。此外,TCP不适用于DNS和SNMP协议。UDP没有任何开销,而TCP有很多开销