为什么具有可靠性的UDP(在应用程序层实现)不能替代TCP?


25

TCP在传输层提供可靠性,而UDP不提供。因此,UDP速度很快。但是,在使用UDP时,应用程序层的协议可以实现可靠的机制。

从这个意义上讲,为什么在我们需要可靠性的情况下UDP比TCP更快的情况下,具有可靠性的UDP(在应用程序层上实现)为什么不能代替TCP?


6
当每个应用程序可以仅依赖于另一个广泛使用的协议(如TCP)时,为什么每个应用程序都提供自己的可靠性机制?
Nakrule

14
以及您如何建议在不减慢堆栈速度的情况下在应用程序层实现可靠性?
JFL

6
由于UDP标头小于TCP标头,因此我们可以利用数据大小。 ”这种想法的问题是,您可能会吃掉带有应用程序层协议标头的UDP有效负载,这会减少应用程序中协议的可用数据。 UDP有效负载。TCP和UDP标头大小之间的差异仅为12个字节。同样,UDP实际上是为较小的有效负载(例如576字节)而设计的。请记住,UDP只会丢失数据报,而数据报中的数据越多,丢失数据报时丢失的数据就越多。
罗恩·莫潘

21
程序员尝试并失败使用UDP创建类似TCP的协议时,堆栈溢出现象盛行。更有经验的程序员告诉他们放弃它,而只使用TCP。他们都认为自己可以做得更好,但这极不可能。
罗恩·莫潘

11
我知道这不是直接成为您的问题的一部分,但是UDP可以做得更好的一个原因是,您只能实现所需的可靠性部分。使用TCP,您可以获得有关订购和交付的可靠性。这意味着TCP在等待重新发送上一条消息时可能会出现打ic。使用UDP,您可以确定所需的只是传递,但是如果有任何消息混乱,您不必等待丢失的消息,只需丢弃它们即可。人们遇到的陷阱是试图复制TCP 100%。在这种情况下,只需使用TCP。
William Mariager

Answers:


47

TCP的可靠性属性可以使您尽快完成任务。如果仅需要排序和错误检测,则可以使UDP完美地发挥作用。这是大多数实时协议(例如语音,视频流等)的基础,其中延迟和抖动比“绝对”纠错更重要。

从根本上说,TCP表示最终可以依赖其流。速度有多快取决于各种计时器,速度等。解决错误所花费的时间可能无法预测,但是在没有错误的情况下,基本操作要尽可能快。如果系统了解可能发生的各种错误,则可能能够执行TCP无法完成的工作。例如,如果极有可能出现单比特错误,则可以对那些比特错误使用纠错编码:但是,这在链接层中要好得多。再举一个例子,如果整个分组丢失的短脉冲很常见,那么您可以通过多次传输来解决这个问题,而不必等待丢失,但是显然这在带宽上很昂贵。或者,降低速度,直到错误概率可以忽略不计:带宽也很昂贵。到底,

从实现的角度来看,您会发现,在TCP上投入了多个世纪的程序员,这将使它比您能负担得起的任何普通产品更快,并且在晦涩的边缘情况下更加可靠。

TCP提供了一种无处不在的连接方法(在通信系统没有通用控制的情况下,这是必不可少的),该方法提供了可靠的,有序的(重复数据删除),双向,窗口化的字节流,并具有对任意距离多跳网络的拥塞控制。

如果某个应用程序不需要普遍存在(您的软件在两侧运行),或者不需要TCP的所有功能,那么很多人通常在UDP之上使用其他协议是有利可图的。例子包括TFTP(极简主义,错误处理效率极低),旨在减少开销的QUIC(仍标记为实验性)和诸如Lidgren之类的库,可对所需的可靠性功能进行精确的控制。 ]


7
自定义“具有可靠性的UDP”协议在视频游戏中也非常普遍。有大量具有各种实现方式的网络库。他们通常希望对数据包进行排序并进行纠错,而不希望重新传输丢失的数据包(并接收所有未来数据包的延迟)。
BlueRaja-Danny Pflughoeft

听起来您在说“ TCP是最佳的通用解决方案,因此它可以原生支持它”。+1
池上

1
@ BlueRaja-DannyPflughoeft有时您需要可靠的无序包(例如,对附近玩家施加的视觉效果)。
user253751

@ BlueRaja-DannyPflughoeft,如果您有典型的示例协议库,我很乐意将其纳入答案
jonathanjo

1
@jonathanjo我使用的一个是lidgren,它支持5种不同的传递方法 (滚动到底部)UnityUnreal Engine也具有在UDP之上构建的自己的网络API。
BlueRaja-Danny Pflughoeft

10

具有可靠性的UDP确实可以替代TCP。我们已经有一个示例:它称为QUIC

从维基百科:

在其他应用程序中,QUIC提高了当前正在使用TCP的面向连接的Web应用程序的性能。通过在两个端点之间通过用户数据报协议(UDP)建立许多多路复用的连接来实现此目的。

使用UDP而不是创建全新的传输层协议的优点是路由器和其他网络设备已经了解它。


QUIC与TCP具有一些不同的特性。在一些情形中(可靠的网络或没有需要加密),它实际上是比较慢:quora.com/...
畸形

您还可以通过sctp将WebRTC数据通道添加到使用UDP的列表中。实际上,当对等体之间无法进行UDP连接时,WebRTC将故障转移至TCP,从而导致性能显着下降。
JSON

在这种情况下,@ freakish slower是一个概括。例如,QUIC将其他数据添加到数据包以减少重传,这会影响吞吐量,但不会影响延迟。
JSON

4

您可以使用UDP在应用程序层上实现TCP功能(可靠性,适应性)。除非使用TCP无法完成您的应用程序真正需要的东西,否则您首先可以使用TCP。如果您自己实现这些功能,则最终可能会比使用TCP更糟糕。增加的开销也降低了整体效率。

TCP的运行速度并不慢-它只需要在传输之前进行一次握手,传输窗口才能适应该通道。它可以很好地调整其通向传输通道的吞吐量,并适应流中的变化,而这一切都是UDP无法做到的(本身)。

但是,传输层之上的协议在这里是不合主题的。


3
“您可以使用UDP在应用程序层上实现TCP功能(可靠性,适应性)” –我认为,这实际上是已经实现QUIC,µTP和SCTP的方式。(尽管如此,我通常认为它们位于传输层的上半部分,而UDP位于下半部分。)
grawity

1
@grawity取决于您的POV-从应用程序的角度来看,中间层是传输层的扩展。从网络(设备)的角度来看,它是应用程序层的全部。
Zac67

4

在干净的网络上,它们相当。在某些情况下,TCP会挂起一段时间(有人见过HTTP屏幕在加载时冻结吗?),但它不会传送垃圾或混淆数据包,并且很少完全放弃。

UDP可以为应用程序层提供对流量的更多控制,而却需要大量工作。

您问题的答案是,有时是那样做的。需要低延迟的游戏通常可以做到这一点。要做很多工作,但是准确控制您可以拥有多少未完成的数据包以及重试它们的频率通常是值得的。

因此,总的来说,不同之处在于TCP是一个非常好的通用实现,但是有一些特定的目的UDP可以使TCP做得很差或根本不做,例如:

  • 永不放弃(使用TCP时,连接有时会挂起,您必须断开连接并重新启动它)
  • 快速发送不需要回复的数据包,并且您不介意偶尔丢失某些数据包(其中只有最近的数据包很重要,其他任何数据包都可以丢弃)-想想游戏位置更新-您可能会得到一些帮助“跳跃”而不是每个步骤,但是您可以更快,更可靠地获得相同的结果。
  • 通过分析数据包丢弃并动态更改重试频率和重试时间来处理iffy网络-甚至可能是最大数据包大小。

但是总的来说,这是不值得的,TCP是最佳选择,那么为什么还要进行所有额外的工作并增加(大)增加错误和安全漏洞的机会?


3

UDP速度不快,因为它是UDP。TCP并不慢,因为它是TCP。

两种协议都设计有一定的保证,并且原始TCP比原始UDP具有更多保证。

经验法则是:保证的价格就是性能

没有什么禁止您通过UDP实现TCP保证的。但是随后您获得了更多的担保,因此您必须付出代价。因此,您将性能降低到TCP或更差(由于UDP开销)。除非您知道更好的TCP实现,否则是不可能的。然后,如果您这样做(很有希望),则可以将其公开,我们将使标准TCP更快。我们回到了起点。:)

您也可以使用这些保证。稍微修改一下,稍微修改一下。然后,您最终获得了像QUIC这样的协议,该协议基于UDP,并且与TCP + TLS 非常相似。在许多情况下,它比TCP快(尽管根据本文,延迟高达5%,最多可缓冲15%,而IMO没什么大不了的),但在某些情况下(例如可靠的网络或不需要加密),实际上速度较慢(请参见此处的说明)。

您也可以削弱这些保证,然后才更有意义。例如,假设您正在流式传输,那么旧数据包就没有意思了。只有最新的。但是拥塞仍然很重要。因此,您可以从TCP获得一些保证,但不是全部。是的,人们实际上是这样做的(例如实时游戏)。这样可以为您提供更好的性能,但需要付出一些保证。


1

您的想法在太空深处会很好。

正确的答案是“取决于”和“因为这将损害整个网络”。TCP / IP对网络非常友好,它会自动调整到合适的速度以加快速度,但不会生成大量的ICMP返回数据包。

当没有足够RAM的路由器突然收到大量的任何类型的数据包(例如,来自海啸,Bittorrent或FDT的数据包)时,它将丢弃该数据包并将其发回给发件人一个小的故障未确认数据包。现在,您的UDP服务器必须手动跟踪并重新传输该部分。一些ISP路由器塑造了Bittorrent,那么多会伤害海啸吗?

海啸协议将UDP与TCP中的控制通道一起使用。http://tsunami-udp.sourceforge.net/我发现一项研究表明,它比称为FDT的事物要慢。

来自CERN的传奇性的快速数据传输(FDT)协议能够使用多个TCP流使任何网络饱和。可能它速度更快,因为它导致的重传次数少于海啸(海啸中大量的UDP淹没了网络),而其中的某些并不能完全覆盖。

UDP被不可靠的应用程序使用:流音频,游戏输入/更新IO,“ ping”实际上是ICMP,但不能保证,Bittorrent,mosh ssh响应速度快,VOIP电话,多播,DNS通过UDP AFAIK发送。任何不介意奇怪的丢失数据包并可以立即“追赶”的事物。

TCP / IP确实是杀手invention的发明,它使应用程序开发人员可以置之不理。套接字是一对IP地址和端口,旨在可以设置并保持数小时,数天甚至数周而无需重新连接。电子邮件,Web,IRC和几乎所有杀手级应用程序都使用TCP。但是下载时可能会出现奇怪的停顿,突然变得更快...而在深空,连接可能会超时,使Tsunami风格的传输最适合星际文件传输-您可能在其中!

证明是在此科学研究摘录的最后一句话中,其中提到了我要进行的关于距离越来越远的事情:深空来自:https : //uscholar.univie.ac.at/get/o : 300623.pdf

在不发生拥塞的情况下,带有TCP的FDT和GridFTP的性能要高于海啸和UDT。FDT的最高吞吐量为2.34 Gb / s,RTT为1毫秒,但与GridFTP相比,它在100毫秒后迅速下降,当链路RTT超过100毫秒时,其性能优于FDT。有趣的是,海啸的吞吐量并未随RTT的增加而下降,这表明随着RTT的增加,海啸具有最有效的拥塞控制。

再说一遍...实际上有一个太空协议,就像电子邮件一样,对于太空来说会更好。这些应用程序不必介意超时值,例如永远。


0

TCP!= UDP +可靠性

TCP不仅仅是具有更高可靠性的UDP。TCP提供的功能不仅仅是可靠性。您可以在许多RFC中了解它们。

这些功能中的任何一个都“可以”在应用程序层实现。最终,您开始重新发明轮子。

仅举几例TCP具有...

  • 连接的创建和终止:执行握手和连接关闭

  • 流控制:确保发送方和接收方以可以处理数据速率的速率进行传输。

  • 端到端拥塞控制:允许端节点根据损失限制其吞吐量。阅读有关启动缓慢,避免拥塞和快速恢复的信息。

以我的经验,当速度是可靠性时,会使用UDP。您可以在应用程序级别添加某些级别的可靠性,该级别不像TCP那样100%可靠。例如,如果您仍然想要快速的性能,则可以实施前向纠错(FEC),在此过程中您可以多次传输数据。您仍然可以获得良好的性能和一定程度的可靠性(请注意TCP可靠性),而无需进行所有来回闲聊以丢失数据包。的好处是,它提高了网络利用率,但可能适合于实时应用程序,例如游戏或流媒体。


最终,您可以将这些额外功能描述为与可靠性有关。
user207421
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.