何时适合使用UDP而不是TCP?
由于TCP保证数据包传输,因此可以被认为是“可靠的”,而UDP不保证任何东西,数据包可能会丢失。 在应用程序中使用UDP而不是通过TCPstream传输数据的优点是什么? 在什么样的情况下UDP会是更好的select,为什么?
我假设UDP更快,因为它没有创build和维护stream的开销,但是如果一些数据永远不会到达目的地,那么这不是无关紧要的吗?
这是我最喜欢的问题之一。 UDP很被误解。
在你真的想快速得到另一台服务器的简单答案的情况下,UDP效果最好。 一般来说,您希望将答案放在一个响应数据包中,并准备好实现自己的可靠性协议或重新发送。 DNS是这个用例的完美描述。 连接设置的成本太高(但DNS也支持TCP模式)。
另外一种情况是当你传递的数据可能会丢失,因为新进来的数据将取代以前的数据/状态。 想到天气数据,videostream,股票报价服务(不用于实际交易)或游戏数据。
另一种情况是,当你pipe理大量的状态时,你想避免使用TCP,因为操作系统不能处理那么多的会话。 今天这是一个罕见的情况。 实际上,现在有了用户态TCP堆栈,可以使用,以便应用程序编写者可以更好地控制TCP状态所需的资源。 在2003年以前,UDP是城里唯一的游戏。
另一种情况是多播stream量。 UDP可以多播到多个主机,而TCP根本不能这样做。
如果TCP数据包丢失,将会重新发送。 这对于那些依靠数据按照特定顺序实时处理的应用程序来说并不方便。
例如videostream,特别是VoIP (例如Skype )。 然而,在这种情况下,丢包并不是什么大问题:我们的感官并不完美,所以我们可能不会注意到。 这就是为什么这些types的应用程序使用UDP而不是TCP。
UDP的“不可靠性”是一种forms主义。 传输不是绝对的保证。 实际上,他们几乎总能通过。 他们只是暂时不承认和重试。
协商TCP套接字和握手TCP数据包的开销是巨大的。 真的很大。 没有可观的UDP开销。
最重要的是,你可以很容易地补充UDP的一些可靠的交付手摇,这比TCPless开销。 阅读: http : //en.wikipedia.org/wiki/Reliable_User_Datagram_Protocol
UDP对于在发布 – 订阅types的应用程序中广播信息是有用的。 IIRC,TIBCO大量使用UDP来通知状态变化。
任何其他types的单向“重大事件”或“日志logging”活动都可以很好地用UDP数据包处理。 你想发送通知而不需要构造整个套接字。 你不会期望来自不同听众的任何回应。
系统“心跳”或“我还活着”的消息也是一个不错的select。 失去一个不是危机。 缺less六打(连续)是。
我工作在支持客户端和服务器之间的UDP(IP)和TCP / IP通信的产品上。 它从15年前的IPX开始,在13年前增加了IP支持。 我们在3年或4年前添加了TCP / IP支持。 疯狂的猜测:UDP到TCP的代码比例大概是80/20。 该产品是数据库服务器,因此可靠性至关重要。 我们必须处理其他答案中已经提到的所有UDP(包丢失,数据包加倍,数据包顺序等)的问题。 几乎没有任何问题,但有时会发生,所以必须处理。 支持UDP的好处是,我们可以根据自己的用途对其进行自定义,并调整更多的性能。
每个networking都会有所不同,但是UDP通信协议对我们来说通常要快一点点。 持怀疑态度的读者会正确地质疑我们是否正确实施了一切。 另外,你可以期望从一个2位数字代表的家伙? 尽pipe如此,我只是因为好奇才进行了testing。 testing阅读100万条logging(selecttable from sometable)。 我将每个客户端请求返回的logging数设置为1,10和100(每个协议有三个testing运行)。 服务器在100Mbit的LAN上只有两跳。 这些数字似乎与其他人在过去发现的一致(UDP在大多数情况下快了大约5%)。 这个特定testing的总时间以毫秒为单位:
- 1logging
- IP:390,760毫秒
- TCP:416,903毫秒
- 10条logging
- IP:91,707毫秒
- TCP:95,662毫秒
- 100条logging
- IP:29,664毫秒
- TCP:30,968毫秒
IP和TCP传输的总数据量大致相同。 我们在UDP通信方面有额外的开销,因为我们有一些与TCP / IP(校验和,序列号等)“免费”相同的东西。 例如,Wireshark显示,对下一组logging的请求是使用UDP的80字节和使用TCP的84字节。
UDP是无连接协议,用于SNMP(简单networkingpipe理协议),DNS(域名系统)等数据包到达不顺序,不可靠和不受关注的应用程序以及数据包直接发送的应用程序。
由于UDP不涉及连接build立,因此需要避免连接build立延迟的DNS等应用,UDP优先于TCP。
在SNMP中使用,因为networkingpipe理通常必须在networking处于紧张状态时才能完成,即当networking可靠时,拥塞控制数据传输难以实现。
干杯
UDP的开销较小,适合stream式传输实时数据(如audio或video),或者在数据丢失的情况下可以。
我知道这个问题的最佳答案之一来自Hacker News的用户zAy0LfpBZLC8mAC 。 这个答案非常好,我现在就引用它。
TCP具有队列头阻塞,因为它保证了完整的和有序的传送,所以当一个数据包在传送中丢失时,它必须等待重传丢失的数据包,而UDP在数据包到达时将数据包传送到应用程序,包括重复,并且没有任何保证,一个数据包全部到达或者它们到达的顺序(实际上它本质上是带有端口号的IP和一个(可选的)有效负载校验和),但是对于电话来说,这是很好的,例如,简单地说毫无疑问,几毫秒的audio丢失,但延迟是非常烦人的,所以你不打扰重发,你只是丢弃任何重复,sorting重新sorting的数据包正确的顺序为几百毫秒的抖动缓冲区,如果数据包没有及时显示,或者根本没有显示,则可以在编解码器支持的位置插入。
此外,TCP的主要部分是stream量控制,以确保您获得尽可能多的througputput,但没有超载networking(这是有点冗余,因为过载的networking会丢弃你的数据包,这意味着你必须做重传,这会影响吞吐量),但是UDP没有这个function – 这对于电话等应用程序来说是有意义的,因为给定编解码器的电话需要一定的带宽,你不能“减慢速度”不会让通话更快。
除了实时/低延迟应用程序之外,UDP对于非常小的事务(例如DNS查找)也很有意义,因为在延迟和带宽使用方面,UDP没有TCP连接build立和拆卸开销。 如果你的请求小于一个典型的MTU,并且repsonse也可能在一个往返中完成,而不需要在服务器上保持任何状态,并且stream量控制等等,所有这些可能并不是特别有用也用于这种用途。
然后,你可以使用UDPbuild立你自己的TCPreplace,当然,如果没有对networkingdynamic的深入理解,这可能不是一个好主意,现代的TCPalgorithm是相当复杂的。
此外,我想应该提到的是,有多于UDP和TCP,如SCTP和DCCP。 目前唯一的问题是(IPv4)互联网充满了NAT网关,这使得在最终用户应用中不可能使用UDP和TCP以外的协议。
这里已经有很多很好的答案,但是我想补充一个非常重要的因素和一个总结。 UDP可以通过正确的调整实现更高的吞吐量,因为它不使用拥塞控制 。 TCP中的拥塞控制非常重要。 它通过尝试估计连接的当前容量来控制连接的速率和吞吐量,以使networking拥塞最小化。 即使数据包通过非常可靠的链路发送,例如在核心networking中,路由器的大小缓冲区也是有限的。 这些缓冲器填满了它们的容量,然后分组被丢弃,并且TCP由于缺less接收到的确认而注意到这一点,并且通过限制连接的速度来估计容量。 TCP也采用了一种叫做慢启动 ( slow start)的技术 ,但吞吐量(实际上就是拥塞窗口 )会慢慢增加,直到丢包,然后再降低,然后再缓慢增加,直到丢包为止。这样会导致TCP吞吐量波动。 您可以在下载大文件时清楚地看到这一点。
因为UDP没有使用拥塞控制,所以它可以更快,并且经历更低的延迟,因为它不会寻求最大化缓冲区直到丢弃点,也就是说,UDP分组在缓冲区中花费更less的时间并以更低的延迟更快地到达那里。 由于UDP不采用拥塞控制,而是采用TCP,所以它可以从TCP产生UDP容量。
UDP仍然容易受到拥塞和丢包的影响,所以你的应用程序必须准备好以某种方式处理这些较less的损失,可能使用重传或纠错码。
结果是UDP可以:
- 只要networking丢包率在应用程序可以处理的范围内,就可以实现比TCP更高的吞吐量。
- 以比TCP更快的速度传送数据包。
- build立连接速度更快,因为没有初始握手来build立连接
- 传输多播数据包,而TCP必须使用多个连接。
- 传输固定大小的数据包,而TCP以分段传输数据。 如果传输300字节的UDP数据包,则在另一端将收到300字节。 使用TCP,你可以提供发送套接字300字节,但接收器只能读取100字节,你必须弄清楚在途中还有200多字节。 如果您的应用程序传输固定大小的消息,而不是字节stream,这一点很重要。
总之,UDP可以用于TCP可以使用的每种types的应用程序,只要你也实现了一个适当的重传机制。 UDP可以非常快速,具有低延迟,在连接的基础上不受拥塞的影响,传输固定大小的数据报并且可以用于多播。
UDP具有较低的开销,如前所述,对于video和audio等stream媒体来说,如果丢失一个数据包,然后尝试重新发送和追赶,那么这样做已经很好了。
在TCP传输方面没有保证,你只是被告知是否sockets断开连接,或者基本上是否数据不会到达。 否则,当它到达那里时,它会到达那里。
人们忘记的一件大事就是udp是基于数据包的,而tcp是基于字节stream的,不能保证你发送的“tcp数据包”是另一端显示的数据包,它可以被分解成尽可能多的数据包作为路由器和堆栈的愿望。 所以你的软件有额外的开销,将字节parsing回可用的数据块,这可能需要相当多的开销。 UDP可能出现故障,所以如果你愿意的话,你必须给你的数据包编号,或者使用一些其他的机制重新排列它们。 但是如果你得到这个udp数据包,它将以相同的顺序到达所有相同的字节,没有改变。 所以术语UDP数据包是有道理的,但TCP数据包并不一定。 TCP有它自己的重新尝试和订购机制,从你的应用程序隐藏,你可以重新发明与UDP来定制它的需要。
UDP在两端编写代码要容易得多,主要是因为你不必build立和维护点对点的连接。 我的问题通常是在什么情况下你会想要TCP开销? 如果你采取快捷方式,假设接收到的tcp“数据包”是发送的完整数据包,你最好过吗? (如果你打算检查长度/内容,你可能会丢掉两个包)
videostream是使用UDP的最佳例子。
video游戏的networking通信几乎总是通过UDP完成的。
速度是最重要的,因为每次更新都包含玩家可以看到的完整当前状态,所以更新是否被忽略并不重要。
在某些情况下,其他人已经强调,保证数据包的到达并不重要,因此使用UDP是很好的。 还有其他情况下,UDP比TCP更可取。
一个你想要使用UDP而不是TCP的独特的例子是你通过另一个协议(例如隧道,虚拟networking等等)将TCP隧道化的地方。 如果通过TCP隧道传输TCP,每个拥塞控制都会相互干扰。 因此,人们通常更喜欢通过UDP(或其他无状态协议)来传输TCP。 请参阅TechRepublic文章: 了解TCP上的TCP:TCP隧道对端到端吞吐量和延迟的影响 。
关键的问题是“UDP会是更好的select(通过TCP)会是什么样的情况”
上面有很多很好的答案,但是缺乏对运输不确定性对技术合作计划绩效影响的任何forms客观的评估。
随着移动应用程序的大量增长以及随之而来的“偶尔连接”或“偶尔断开连接”的范例,肯定会出现这样的情况:当连接难以达到时TCP的尝试维持连接的开销导致强UDP的情况和它的“消息导向”性质。
现在我没有这方面的math/研究/数字,但是我制作的应用程序在连接性一般差的时候使用ACK和NAK以及通过UDP进行消息编码的可靠性比使用TCP可以实现得更可靠,而旧的TCP只是花时间和我的客户的钱只是试图连接。 你在许多西方国家的地区和农村得到这个…
当应用程序更关心“实时”数据而不是精确的数据复制时,可以使用UDP。 例如,VOIP可以使用UDP,应用程序会担心重新sorting数据包,但最终VOIP并不需要每一个数据包,但更重要的是需要连续的stream量。 也许你在这里的语音质量有一个“小故障”,但主要目的是你得到的信息,而不是它在另一边完美再造。 UDP也用于创build连接和与TCP同步的成本超过有效负载的情况。 DNS查询就是一个很好的例子。 每个查询一个数据包,一个数据包返回。 如果使用TCP,这将更encryption集。 如果你没有得到DNS的回应,你只是重试。
当速度是必要的时候是UDP,如果数据包不准确则是准确的。
UDP通常比较难,因为你必须以不依赖于数据包准确性的方式编写你的程序。
这并不总是明确的。 但是,如果你需要保证数据包没有丢失并按正确的顺序传输,那么TCP可能就是你想要的。
另一方面,UDP适用于在信息序列不那么重要或者数据可以放入单个分组的情况下传输短的信息分组。
当您想要向许多用户广播相同的信息时也是适当的。
其他时候,当你发送序列数据的时候是合适的,但是如果有一些丢失,你不会太在意(例如一个VOIP应用程序)。
有些协议比较复杂,因为需要的是TCP的一些(但不是全部)特性,但是比UDP提供的要多。 这就是应用程序层必须实现附加function的地方。 在这些情况下,UDP也是合适的(例如互联网广播,订单很重要,但不是每个数据包都需要通过)。
可以使用的示例1)时间服务器将正确的时间广播给局域网上的一堆机器。 2)VOIP协议3)DNS查找4)请求LAN服务,例如你在哪里? 5)互联网广播6)和其他许多…
在UNIX上,你可以inputgrep udp / etc / services来获得今天实现的UDP协议列表……有数百个。
请参阅Steven的Unixnetworking编程第22.4节“何时使用UDP而不是TCP”。
此外,看到这个其他答案关于UDP总是比TCP更快的误解 。
史蒂文所说的可以概括如下:
- 使用UDP广播和多播,因为这是你唯一的select(使用多播的任何新的应用程序)
- 您可以使用UDP进行简单的请求/回复应用程序,但是您需要构build自己的ack,超时和重新传输
- 不要使用UDP进行批量数据传输。
在这种情况下,您希望使用基于TCP的UDP,在这种情况下丢失一些数据不会完全破坏正在传输的数据。 它的许多用途是在实时应用程序中,例如游戏(即FPS),在这种应用程序中,您并不总是必须知道每个玩家在任何给定时间的位置,如果您在此过程中丢失了一些数据包,数据将正确地告诉你玩家在哪里),和实时videostream(一个腐败的框架不会毁了观看体验)。
我们有networking服务,有数以千计的WinForms客户端在尽可能多的个人电脑。 PC与DB后端没有连接,所有的访问都是通过Web服务进行的。 所以我们决定开发一个监听UDP端口的中央日志logging服务器,所有的客户端都会收到一个xml错误日志包(使用log4net UDP appender),转发到数据库表。 由于我们并不关心是否错过了几个错误日志,并且有数以千计的客户端,因此不需要加载主要的Web服务就可以使用专用的日志logging服务。
我们知道UDP是无连接协议,所以它是
- 适合需要简单的请求 – 响应通信的进程。
- 适合有内部stream程,错误控制的stream程
- 适用于广播和组播
具体例子:
- 在SNMP中使用
- 用于RIP等路由更新协议
比较TCP和UDP,UDP等无连接协议可以保证速度,但不能保证数据包传输的可靠性。 例如在video游戏中,通常不需要可靠的networking,但速度是最重要的,使用UDP进行游戏具有减lessnetworking延迟的优点。
当TCP可能工作时,我有点不情愿推荐UDP。 问题是,如果TCP由于某种原因而不工作,因为连接太滞后或拥塞,将应用程序更改为使用UDP不太可能有所帮助。 坏的连接对UDP也不好。 TCP已经在减less拥塞方面做了很好的工作。
我能想到的唯一的例子就是广播协议。 在应用程序涉及两个已知的主机的情况下,UDP可能仅仅为代码复杂度的显着增加的成本提供边际性能益处。
只有使用UDP,如果你真的知道你在做什么。 目前,UDP在极less数情况下是可用的,但许多(甚至非常有经验的)专家试图在任何地方坚持它似乎是不成比例的。 也许他们喜欢自己实现error handling和连接维护代码。
由于所谓的校验和印记,使用现代networking接口卡预计TCP要快得多。 令人惊讶的是,计算校验和的快速连接速度(例如1Gbps)对于CPU来说是一个很大的负担,所以它被卸载到识别TCP数据包的网卡硬件上,并且不会提供相同的服务。
UDP是完美的VoIP寻址数据包必须发送的可靠性较差…video聊天是UDP的一个例子(你可以通过在任何video聊天wiresharknetworking捕获)。此外TCP不工作DNS和SNMP协议。 UDP没有任何开销,而TCP有很多开销