什么时候使用UDP代替TCP?[关闭]


302

由于TCP保证了数据包的传递,因此可以被认为是“可靠的”,而UDP不保证任何内容,因此数据包可能会丢失。在应用程序中而不是通过TCP流使用UDP传输数据的优势是什么?在哪种情况下,UDP是更好的选择,为什么?

我假设UDP更快,因为它没有创建和维护流的开销,但是如果某些数据永远不会到达目的地,那不是无关紧要的吗?


55
UDP可能会遭受数据包丢失的困扰,但不能保证您只会收到一次数据包。如果网络混乱或配置不正确,则可以多次接收相同的数据包。因为人们往往会忘记这一点,所以要小心!
布赖恩·阿格纽

3
它甚至不保证包排序。
Mehrdad Afshari

19
TCP不保证传递,它只是保证如果能够传递数据包,它们将以它们发送的顺序。
Chaim Geretz 2011年

5
顺便说一句,我经常看到人们将可靠性/按顺序传递等同于TCP重传。这些“专家”将告诉您,要克服UDP上的传输错误,您将(非常困难)重新实现TCP,因此您不妨使用TCP。 这不是真的。 除了重传以外,还有其他错误恢复技术,这些方法不会由于小但非零的错误率而遭受延迟或吞吐量的指数级降低。
Ben Voigt 2014年

TCP还可以确保您知道目的地是否未接收到数据包。
csga5000

Answers:


353

这是我最喜欢的问题之一。UDP被误解了。

如果您确实希望快速获得对另一台服务器的简单答复,则UDP效果最佳。通常,您希望答案在一个响应包中,并且您准备实现自己的协议以提高可靠性或重新发送。DNS是此用例的完美描述。建立连接的成本太高了(但是,DNS确实也支持TCP模式)。

另一种情况是当您传递的数据可能会丢失,因为传入的新数据将替换先前的数据/状态。我想到了天气数据,视频流,股票报价服务(不用于实际交易)或游戏数据。

另一种情况是,当您管理大量状态时,由于操作系统无法处理那么多会话,因此您希望避免使用TCP。今天,这种情况很少见。实际上,现在可以使用用户级TCP堆栈,以便应用程序编写器可以对该TCP状态所需的资源进行更精细的控制。在2003年之前,UDP确实是该镇唯一的游戏。

另一种情况是多播流量。UDP可以组播到多个主机,而TCP根本不能这样做。


感谢您的有趣回答。我们有一台服务器当前正在UDP中执行所有操作(高带宽要求),这是可以的,因为确实存在单跳(路由已禁用,...),但是已经注意到,在某些故障的网卡上,数据包的重新排序可能会成为问题。您建议使用哪种用户模式的TCP(或其他受用户模式控制的流量)堆栈?
破旧的2013年

@dashesy-您可以摆脱订购要求吗?您可以使用的有效负载中是否有单调递增的数字?如果是这样,您实际上并不需要完整的用户态TCP堆栈。
drudru

@ drudru-是的,序列号在那里,我可能需要自己缓冲和消除抖动。谢谢,消除其他选择总是很不错的。
2013年

63

如果TCP数据包丢失,它将被重新发送。对于依赖于以特定顺序实时处理数据的应用程序而言,这并不方便。

示例包括视频流,尤其是VoIP(例如Skype)。但是,在这些情况下,丢包并不是什么大问题:我们的感觉并不完美,因此我们甚至可能不会注意到。这就是为什么这些类型的应用程序使用UDP而不是TCP。


16
我想你倒退了。TCP对数据包进行重新排序,以便按发送顺序传送数据。UDP不会重新排序,并可以以任意顺序它收到它提供的数据。
汉斯·马勒布

1
UDP不保证顺序,但是您可以对数据包编号,然后在重新整理数据包后对其重新排序。
Kugel,

7
@ Stephan202:我想我不同意在Skype中不注意丢包的问题;-)
Robert S. Barnes 2010年

6
@Kugel:请注意,您可能正在实现新的TCP堆栈。在这方面,您不太可能比操作系统做得更好。
erikkallen 2010年

1
@erikkallen:如果使用UDP来实现更高的协议,而TCP可以满足相同的要求,那么它就不可能比现有协议做得更好。另一方面,某些应用程序受益于协议的一些附加功能,UDP包装程序可以比TCP处理更好的功能。
supercat

56

UDP的“不可靠性”是形式主义。传输不是绝对保证的。实际上,它们几乎总是能够通过。超时后,它们不会被确认并重试。

协商TCP套接字和握手TCP数据包的开销很大。真的很大。没有明显的UDP开销。

最重要的是,您可以通过一些可靠的交付握手协议轻松地补充UDP,而这些握手开销要比TCP少。阅读此:http : //en.wikipedia.org/wiki/Reliable_User_Datagram_Protocol

UDP对于在发布-订阅类型的应用程序中广播信息很有用。IIRC,TIBCO大量使用UDP来通知状态更改。

UDP数据包可以很好地处理任何其他类型的单向“重要事件”或“记录”活动。您要发送通知而无需构造整个套接字。您不会期望各种听众有任何回应。

系统“心跳”或“我还活着”的消息也是一个不错的选择。错过一个不是危机。(连续)丢失六打。


5
“实际上,他们几乎总是能够通过。” 高度取决于较低的网络层可靠性。
m0skit0 '16

此外,计划“少量”分组丢失和“过多”分组丢失之间是否有区别?损失就是损失。无论如何,您必须为此计划。
塞达特·卡帕诺格鲁

30

我正在开发一种同时支持客户端和服务器之间的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%)。此特定测试的总时间(以毫秒为单位)如下:

  1. 1条记录
    • IP:390,760毫秒
    • TCP:416,903毫秒
  2. 10条记录
    • IP:91,707毫秒
    • TCP:95,662毫秒
  3. 100条记录
    • IP:29,664毫秒
    • TCP:30,968毫秒

对于IP和TCP,传输的总数据量大致相同。UDP通信会产生额外的开销,因为我们拥有一些您可以免费使用TCP / IP获得的相同内容(校验和,序列号等)。例如,Wireshark显示对下一组记录的请求是UDP的80字节,TCP的84字节。


如果您仅为TCP开发了它并且购买了更好的硬件而不是5倍的编码工作量怎么办?
inf3rno

2
感谢具体数字!5%的改进对于它增加的复杂性有些令人失望。
谢尔盖

1
5%可能是因为是在本地网络中发送的(两个希望寄予了希望)?我的猜测是,距离越远,差异越大。
lepe

19

这里已经有很多好的答案,但是我想补充一个非常重要的因素以及摘要。UDP通过正确的调整可以实现更高的吞吐量,因为它不使用拥塞控制。TCP中的拥塞控制非常非常重要。它通过尝试估计连接的当前容量来控制连接的速率和吞吐量,以最大程度地减少网络拥塞。即使通过非常可靠的链路(例如在核心网络中)发送数据包,路由器的缓冲区大小也有限。这些缓冲区填满其容量,然后丢弃数据包,TCP通过缺少接收到的确认来通知此丢失,从而限制了连接速度以估算容量。TCP还采用了一种称为“ 慢启动”的方法,但是吞吐量(实际上是拥塞窗口))缓慢增加直到丢包,然后降低然后再次缓慢增加直到丢包等。这导致TCP吞吐量波动。下载大文件时,您可以清楚地看到这一点。

因为UDP不使用拥塞控制,所以它既可以更快,又可以减少延迟,因为UDP不会设法最大化缓冲区直到丢失点,即UDP数据包在缓冲区中花费的时间更少,并且延迟更短而到达那里。由于UDP不采用拥塞控制,而TCP则采用拥塞控制,因此它可以占用TCP到UDP流的容量。

UDP仍然容易受到拥塞和丢包的影响,因此您的应用程序必须准备好以某种方式处理这些复杂情况,可能使用重传或纠错码。

结果是UDP可以:

  • 只要网络丢失率在应用程序可以处理的范围内,就可以获得比TCP更高的吞吐量。
  • 传送数据包的速度比TCP更快,延迟更少。
  • 建立连接的速度更快,因为没有初始握手即可建立连接
  • 传输多播数据包,而TCP必须使用多个连接。
  • 传输固定大小的数据包,而TCP分段传输数据。如果传输300字节的UDP数据包,则另一端将收到300字节。使用TCP,您可以向发送套接字提供300字节的数据,但是接收方只能读取100字节的数据,因此您必须弄清楚还有200字节的数据。如果您的应用程序传输固定大小的消息,而不是字节流,则这一点很重要。

总之,只要您还实现适当的重传机制,UDP便可以用于TCP可以使用的每种类型的应用程序。UDP可以非常快,具有较少的延迟,不受连接拥塞的影响,可以传输固定大小的数据报,并且可以用于多播。


1
当网络变得足够拥塞以致造成数据包丢失时,TCP会尽量减少其对网络其他用户的影响,而许多基于UDP的实现则不会。这样一来,他们可以抢占越来越大的市场份额,但也减少了可用带宽的可用时间总量(例如,在实际上将要发送数据但发送者不知道的情况下,由于不必要的重传而导致的结果)
超级猫

首先,感谢您的出色回答,我确实从中学到了很多东西!但是我有一个问题:由于以太网适配器对从第4层收到的所有数据包(TCP和UDP)的限制,在第3层(IP)上不会发生分段吗?您是说发生在TCP中但不在UDP中发生任何其他类型的分段吗?如果您能向我解释,我将不胜感激。
RuslanSh

1
@Freezy。没错,超出链路(第2层)MTU的数据包的碎片发生在第3层IP。但是,TCP是基于流的协议,它将数据视为字节流。TCP确实按段发送数据以适合IP数据包(根据MSS调整大小),因此分段也确实在TCP中发生。但是,TCP放入段中的数据量,或者套接字读取的数据量取决于许多因素。它可以是1个字节或MSS字节。使用UDP,如果数据包在途中没有丢失,则接收方始终可以获得发送方发送的确切字节数。
安迪

15

UDP是一种无连接协议,用于SNMPDNS之类的协议中,其中数据包无序到达是可接受的,并且数据包的立即传输很重要。

它在SNMP中使用,因为网络管理通常必须在网络处于紧张状态时完成,即在难以实现可靠的,由拥塞控制的数据传输时。

由于它不涉及连接建立,因此在DNS中使用它,从而避免了连接建立延迟。

干杯


14

UDP确实具有较少的开销,并且适合执行诸如流传输实时数据(如音频或视频)之类的事情,或者在任何情况下如果数据丢失都可以。


12

对于这个问题,我知道最好的答案之一来自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运行SCTP和DCCP。
黛咪


8

UDP具有较低的开销,如上所述,它对于流传输诸如视频和音频之类的内容非常有用,最好丢掉一个数据包然后尝试重新发送并赶上。

TCP传输没有任何保证,仅应告知您套接字是否已断开连接,或者基本上是如果数据不会到达。否则它到达那里时就到达那里。

人们忘记的一个大事是udp是基于数据包的,而tcp是基于字节流的,因此不能保证您发送的“ tcp数据包”是在另一端显示的数据包,可以将其分解为尽可能多的数据包如路由器和堆栈所希望的。因此,您的软件具有将字节解析回可用数据块中的额外开销,这可能会花费相当多的开销。UDP可能会乱序,因此您必须对数据包编号,或者如果需要的话,可以使用其他某种机制对其进行重新排序。但是,如果您获得了该udp数据包,则该数据包将以所有相同的字节到达,并且顺序与原来的顺序相同,没有任何变化。因此,术语udp数据包有意义,而tcp数据包则不一定。TCP具有自己的重试和排序机制,对您的应用程序是隐藏的,

UDP在两端都更容易编写代码,基本上是因为您不必建立和维护点对点连接。我的问题通常是在什么情况下需要TCP开销?而且,如果您采取一些捷径,例如假设接收到的TCP“数据包”是已发送的完整数据包,那么您的状况更好吗?(如果您费心检查长度/内容,则可能会丢掉两个数据包)


TCP确实具有传递保证:块A将在块B之前传递给应用程序,因此,如果应用程序(在应用程序级别)确认块B,则您知道它获得了块A。但这也发生在TCP处理级别。
Simeon朝圣者

在TCP中,只需为每个数据块添加前缀就可以安全地分隔数据块。取决于应用,可以为每个块添加固定的一字节,两字节或四字节长度的前缀,或者可以为每个大小为128 ^ N或更小的块添加N字节的长度前缀。不完全是巨大的开销。这样的设计对于不能保证没有间隙的按顺序交付的协议将是不好的,但是当使用TCP时,这样的设计就可以了。
supercat

如果要查找固定长度的数据,您甚至不需要长度,只要对字节进来就可以计数...
old_timer 2013年

1
@supercat。你是绝对正确的。这也意味着您正在增加应用程序的复杂性。UDP实际需要的复杂性。因此,TCP更适合传输文件等流。但是,当我想要分块数据的可靠性以及顶层TCP上的TLS额外的安全性时,我会做您所需要的。
安迪

5

视频游戏的网络通信几乎总是通过UDP完成。

速度是最重要的,是否错过更新并不重要,因为每次更新都包含玩家可以看到的完整当前状态。


5
正常情况下根本不是完整状态,而是自上次确认以来的增量,因此更新会逐渐变大。
Simeon朝圣者

5

关键问题与“在[TCP]上UDP是哪种情况更好”有关。

上面有很多很好的答案,但是缺少对运输不确定性对TCP性能的影响的任何正式,客观的评估。

随着移动应用程序的迅猛发展,以及随之而来的“偶发连接”或“偶发断开”的范例,在某些情况下,当难以建立连接时,TCP尝试维护连接的开销会导致强大的性能。 UDP及其“面向消息”的性质。

现在我还没有数学/研究/编号,但是我生产的应用程序使用UDP进行ACK / NAK和消息编号时比使用TCP时无法实现的可靠性更高,而当连接性普遍较差且旧TCP较差时,只是花时间,而我客户的钱只是在尝试联系。您可以在许多西方国家的地区和农村地区获得此服务。


3

在某些情况下(其他情况已强调),保证数据包的到达并不重要,因此使用UDP很好。在其他情况下,UDP比TCP更可取。

您想使用UDP而不是TCP的一种独特情况是,您通过另一种协议(例如,隧道,虚拟网络等)建立TCP隧道。如果在TCP之上通过TCP隧道传输,则每个拥塞控制都会相互干扰。因此,人们通常更喜欢在UDP(或其他一些无状态协议)上建立TCP隧道。请参阅TechRepublic文章:了解TCP之上的TCP:TCP隧道对端到端吞吐量和延迟的影响


2

当应用更关心“实时”数据而不是精确的数据复制时,可以使用UDP。例如,VOIP可以使用UDP,而该应用程序将担心重新排序数据包,但最终VOIP不需要每个数据包,但更重要的是需要其中许多数据的连续流。也许您在这里的语音质量有些“毛刺”,但主要目的是让您收到消息,而不是在另一端完美地重新创建了消息。在创建连接并与TCP同步的开销超过有效负载的情况下,也可以使用UDP。DNS查询就是一个很好的例子。每个查询一个包,一个包返回。如果使用TCP,则将更加密集。如果没有返回DNS响应,则重试。


2

如果需要速度,则为UDP;如果不需要数据包,则为准确性;而当需要准确性时,则为TCP。

UDP通常更难,因为您必须以不依赖于数据包准确性的方式编写程序。


2

这并不总是很明确。但是,如果您需要保证数据包的传输没有丢失并且按正确的顺序进行传输,则可能需要TCP。

另一方面,UDP适用于在信息序列不太重要或数据可以放入单个数据包的情况下传输短信息包。

当您要将相同的信息广播给许多用户时,这也是合适的。

其他时候,当您发送排序的数据时比较合适,但是如果其中一些丢失了,则不必太担心(例如VOIP应用程序)。

有些协议更为复杂,因为所需的只是TCP的某些(但不是全部)功能,而不仅仅是UDP提供的功能。那是应用程序层必须实现附加功能的地方。在那些情况下,UDP也适用(例如,互联网广播,顺序很重要,但并非每个数据包都需要通过)。

可以/可以在何处使用的示例1)时间服务器向LAN上的一堆机器广播正确的时间。2)VOIP协议3)DNS查找4)请求LAN服务,例如您在哪里?5)网络广播6)和许多其他...

在Unix上,您可以键入grep udp / etc / services以获得今天实现的UDP协议列表...有数百种。


2

查看Steven的Unix网络编程的 22.4节 “何时使用UDP代替TCP”。

另外,请参阅有关SO 误解的其他SO答案,即UDP总是比TCP快。

史蒂文的话可以总结如下:

  • 使用UDP进行广播和多播,因为这是您唯一的选择(将多播用于任何新应用)
  • 您可以将UDP用于简单的请求/回复应用,但是您需要构建自己的ack,超时和重传
  • 不要使用UDP进行批量数据传输。

1
有关最后一点的更多信息,适用于所有后来的人。TCP适用于批量数据传输,但是如果您不关心数据以从头到尾的顺序到达,则可以通过UDP编写一个协议,该协议可能会更快-在非常特殊的病理情况下要快得多。这并不是说您无法在UDP中进行批量传输,并不是说它总是性能较差;实施起来实在是太痛苦了,很少值得去理会。
ijw 2010年

1
是的,您可以使用UDP进行批量传输,并且必须实现自己的控制机制。到底是不是要付出多少辛苦取决于您的编程技能,但它的性能肯定并不总是那么差。你必须知道你在做什么。如果您不这样做,那么您可能会遭受痛苦。
安迪

2

我们知道UDP是一种无连接协议,因此

  1. 适用于需要简单的请求-响应通信的过程。
  2. 适用于内部流程,错误控制的过程
  3. 适用于广泛的广播和组播

具体示例:

  • 在SNMP中使用
  • 用于某些路由更新协议,例如RIP

2

将TCP与UDP进行比较,无连接协议(如UDP)可确保速度,但不能保证数据包传输的可靠性。例如,在视频游戏中,通常不需要可靠的网络,但是速度是最重要的,并且将UDP用于游戏具有减少网络延迟的优势。

在此处输入图片说明


1

在沿途丢失某些数据不会完全破坏正在传输的数据的情况下,您想使用基于TCP的UDP。它的许多用途都用于实时应用程序中,例如游戏(例如FPS),您不必总是知道每个给定时间每个玩家的位置,如果您在此过程中丢失了一些数据包,数据会正确地告诉您播放器的位置,以及实时视频流(一个损坏的帧不会破坏观看体验)。


好吧,一个损坏的帧会破坏那部分视图,但是如果后面的帧比丢失的帧具有更大的价值,则您不希望它在等待时停止所有后面的帧。
Simeon朝圣者

1

我们拥有的Web服务在许多PC上都具有数千个winforms客户端。PC与数据库后端没有连接,所有访问都通过Web服务进行。因此,我们决定开发一个中央记录服务器,该服务器侦听UDP端口,并且所有客户端发送xml错误日志包(使用log4net UDP附加程序),并在接收到时将其转储到DB表中。由于我们并不真正在乎是否丢失了一些错误日志,而对于成千上万的客户端而言,专用的日志记录服务却不会加载主要的Web服务,因此速度很快。


0

当TCP可能工作时,我不太愿意建议UDP。问题是,如果由于某种原因TCP无法正常工作,因为连接太慢或太拥挤,那么更改应用程序以使用UDP不太可能有帮助。错误的连接对UDP也有害。TCP已经在减少拥塞方面做得非常好。

我能想到的唯一情况是广播协议需要UDP。在一个应用程序涉及两个已知主机的情况下,UDP可能仅会带来边际性能优势,同时会大大增加代码复杂性的成本。


如果中间节点正在执行流量监管,则可以通过UDP测试通过UDP获得更好的结果的一个应用程序,因为您可以更轻松地控制数据包速率,TCP可以快速推送数据包以及TCP的交互窗口化与治安产生负面影响。
Simeon朝圣者

这仍然是一种优化,应该在实际测试之后进行。我的观点是,您仍然应该首先尝试使用TCP,并且仅当发现TCP由于某种原因无法正常工作时,才尝试使用替代方法。选择UDP,因为它理论上支持更好的带宽使用,这是过早优化的一种形式。
SingleNegationElimination

哦,在最优化方面同意。但是,当您尝试解决性能问题时,了解何时使用TCP可能会成为问题,以及其他方面的帮助。
Simeon朝圣者

-1

仅当您真正知道自己在做什么时才使用UDP。UDP在当今极为罕见的情况下,但是试图将其粘贴到任何地方的(甚至非常有经验的)专家的数量似乎不成比例。也许他们喜欢自己实现错误处理和连接维护代码。

由于所谓的校验和烙印,应该期望现代网络接口卡的TCP更快。出乎意料的是,在快速的连接速度(例如1Gbps)下,计算校验和对于CPU来说将是一个很大的负担,因此它会分流到可识别TCP数据包以进行标记的NIC硬件上,并且不会为您提供相同的服务。


2
UDP校验和卸载与TCP校验和卸载一样可用。
Ben Voigt 2014年

但不是校验和验证。
Pavel Radzivilovsky 2014年

1
甚至当今的消费者级以太网适配器都具有用于发送和接收的UDP校验和卸载(接收卸载正在进行验证)。十年前,我在生产者专用硬件中看到了该功能,我确信它在服务器级NIC中的使用时间甚至更长。
Ben Voigt 2014年

-2

UDP非常适合VoIP寻址,而不必考虑其可靠性,而必须发送数据包。视频聊天是UDP的一个示例(您可以在任何视频聊天期间通过Wireshark网络捕获对其进行检查)。此外,TCP不适用于DNS和SNMP协议。UDP没有任何开销,而TCP有很多开销

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.