但是,应用层的协议在使用UDP时可以实现可靠的机制。
从这个意义上讲,为什么在我们需要可靠性的情况下UDP比TCP更快的情况下,具有可靠性的UDP(在应用层上实现)为什么不能代替TCP? >
#1 楼
TCP的可靠性属性可以使您尽快完成任务。如果仅需要排序和错误检测,则可以使UDP完美地发挥作用。这是大多数实时协议(例如语音,视频流等)的基础,在这些协议中,滞后和抖动比“绝对”纠错更为重要。最终。速度有多快取决于各种计时器,速度等。解决错误所花费的时间可能无法预测,但是在没有错误的情况下,基本操作要尽可能快。如果系统了解可能发生的错误种类,则可能能够执行TCP无法完成的工作。例如,如果极有可能出现单比特错误,则可以对这些比特错误使用纠错编码:但是,这在链接层中要好得多。再举一个例子,如果整个分组丢失的短脉冲很常见,那么您可以通过多次传输来解决这个问题,而不必等待丢失,但是显然这在带宽上很昂贵。或者,减慢速度,直到错误概率可以忽略不计:带宽也很昂贵。最后,协议必须以a)带宽或b)延迟来保证可靠性。在实现方面,您会发现投资TCP的程序员世纪比任何事情都要快。一般情况下,您可以负担得起,并且在晦涩的边缘情况下更可靠。 ,(和重复数据删除)两种方式的窗口化字节流,具有对任意距离多跳网络进行拥塞控制的功能。
如果某个应用程序不需要普遍存在(您的软件在两侧运行),或者不需要TCP的所有功能,那么很多人通常在UDP之上使用其他协议就能获利。例子包括TFTP(极简主义,错误处理效率极低),旨在减少开销的QUIC(仍标记为实验性)和诸如Lidgren之类的库,可精确控制所需的可靠性功能。 ]
评论
自定义“具有可靠性的UDP”协议在视频游戏中也非常普遍。有大量具有各种实现方式的网络库。他们通常希望对数据包进行排序并进行纠错,而不希望重新传输丢失的数据包(并接收所有未来数据包的延迟)。
– BlueRaja-Danny Pflughoeft
19年6月27日在20:19
听起来您在说“ TCP是最佳的通用解决方案,因此可以原生支持它”。 +1
–池上
19年6月27日在23:01
@ BlueRaja-DannyPflughoeft有时您需要可靠的无序数据包(例如,对附近玩家施加的视觉效果)。
–user253751
19 Jun 28'在0:38
@ BlueRaja-DannyPflughoeft,如果您有典型的示例协议库,我很乐意将其纳入答案
– jonathanjo
19年6月28日在12:45
@jonathanjo我使用的一个是Lidgren,它支持5种不同的传送方式(滚动到底部)。 Unity和Unreal Engine还具有在UDP之上构建的自己的网络API。
– BlueRaja-Danny Pflughoeft
19-6-28在17:19
#2 楼
具有可靠性的UDP确实可以替代TCP。我们已经有一个示例:它被称为QUIC。来自Wikipedia:目前正在使用TCP。它通过在两个端点之间通过用户数据报协议(UDP)建立许多多路复用的连接来实现此目的。和其他网络设备已经了解它。
评论
QUIC与TCP有一些不同的特性。在某些情况下(可靠的网络或无需加密),它实际上要慢一些:quora.com/…
–怪异的
19-6-28在10:42
您还可以通过sctp将WebRTC数据通道添加到使用UDP的列表中。实际上,当对等体之间无法进行UDP连接时,WebRTC将故障转移到TCP,从而导致性能显着下降。
– JSON
19年6月30日在9:42
在这种情况下,@ freakish slower是一个概括。例如,QUIC将其他数据添加到数据包以减少重传,这会影响吞吐量,但不会影响延迟。
– JSON
19年6月30日在9:50
#3 楼
您可以使用UDP在应用程序层上实现TCP功能(可靠性,适应性)。除非使用TCP无法完成您的应用程序真正需要的东西,否则您首先可以使用TCP。如果您自己实现这些功能,则最终可能会比使用TCP更糟糕。增加的开销也会降低整体效率。TCP并不慢-它只需要在传输前握手,传输窗口就可以适应信道。它可以很好地调整其通向传输通道的吞吐量,并适应流中的变化,而这一切都是UDP无法做到的(单独实现)。不在这里。
评论
“您可以使用UDP在应用程序层上实现TCP功能(可靠性,适应性)” –我认为,这实际上是已经实现QUIC,µTP和SCTP的方式。 (尽管如此,我通常认为它们位于传输层的上半部分,而UDP位于下半部分。)
–user1686
19-6-27在15:43
@grawity取决于您的POV-从应用程序的角度来看,中间层是传输层的扩展。从网络(设备)的角度来看,它是应用程序层的全部。
– Zac67
19年6月27日在18:17
#4 楼
在干净的网络上,它们相当。在某些情况下,TCP会挂起一段时间(有人见过HTTP屏幕在加载时冻结吗?),但它不会传递垃圾或混合数据包,很少完全放弃。层以更多的工作为代价对流量进行更多控制。需要低延迟的游戏通常可以做到这一点。要做很多工作,但是准确控制您可以拥有的未处理数据包的数量和重试频率的能力通常是值得的。一般用途的实现,但是UDP可以实现TCP的某些特殊目的,要么做得很差,要么根本不做,例如:并且必须断开连接并重新启动它)发送不需要回复的快速数据包流,并且您不介意偶尔丢失某些数据包(其中只有最新的数据包很重要,其他任何数据包都可以丢弃))(考虑游戏位置的更新),您可能会得到一些“跳跃”,而不是每个步骤,但是您可以更快,更可靠地获得相同的结果。经常以及您重试的时间-甚至可能是最大数据包大小。
但是总的来说我不值得t,TCP绝对是最佳选择,那么为什么还要进行所有额外的工作并增加(大)增加错误和安全漏洞的机会?
#5 楼
UDP速度不快,因为它是UDP。 TCP并不慢,因为它是TCP。这两个协议都设计有一定的保证,并且原始TCP比原始UDP具有更多的保证。
经验法则是:保证的代价就是性能。
没有什么可以阻止您通过UDP实现TCP保证。但是随后您获得了更多的担保,因此您必须付出代价。因此,您将性能降低到TCP或更差(由于UDP开销)。除非您知道更好的TCP实现,否则是不可能的。然后,如果您这样做(很有希望),则可以将其公开,我们将使标准TCP更快。我们回到了起点。 :)
您也可以使用这些保证。稍微修改一下,稍微修改一下。然后,您最终获得了像QUIC这样的协议,该协议基于UDP,并且与TCP + TLS非常相似。在许多情况下,它比TCP快(尽管根据本文,延迟高达5%,缓冲高达15%,而IMO没什么大不了的),但在某些情况下(例如可靠的网络或不需要加密)速度较慢(请参阅此处的说明)。
您还可以削弱这些保证,然后变得更有意义。例如,假设您正在流式传输,那么旧数据包就没有意思了。只有最新的。但是拥塞仍然很重要。因此,您可以从TCP获得一些保证,但不是全部。是的,人们实际上是这样做的(例如实时游戏)。这样可以为您提供更好的性能,但需要付出一些保证。
#6 楼
您的想法在太空深处会很好。正确的答案是“取决于”和“因为这将损害整个网络”。 TCP / IP对网络非常友好,可以自动调整到适当的速度,但速度很快,但不会生成大量的ICMP返回数据包。
当RAM不足的路由器突然收到很多其他信息时数据包(例如来自海啸,Bittorrent或FDT的数据包)将其丢弃,然后向发送方发回一个小的故障取消确认数据包。现在,您的UDP服务器必须手动跟踪并重新传输该部分。一些ISP路由器塑造了Bittorrent,那么多会伤害海啸吗?
Tsunami协议使用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毫秒。有趣的是,海啸的吞吐量并未随RTT的增加而降低
,表明随着RTT的增加,海啸具有最有效的拥塞控制。
然后再次...实际上,有一个类似于电子邮件的空间协议,它将对空间更好。应用程序不必介意超时值,例如永远。
#7 楼
TCP!= UDP +可靠性TCP不仅仅是具有增强可靠性的UDP。 TCP提供的功能不仅仅是可靠性。您可以在许多RFC中了解它们。
“可以”在应用程序层实现任何这些功能。最终,您开始重新发明轮子了。
TCP具备的一些功能……连接关闭
流控制:确保发送方和接收方以可以处理数据速率的速率进行传输。
端到端拥塞控制:允许端节点根据损耗限制其吞吐量。阅读有关启动缓慢,避免拥塞和快速恢复的信息。
以我的经验,当速度是可靠性的问题时,使用UDP。您可以在应用程序级别添加某些级别的可靠性,该级别不像TCP那样100%可靠。例如,如果您仍然想要快速的性能,则可以实施前向纠错(FEC),在该过程中您可以多次传输数据。您仍然可以获得良好的性能和一定程度的可靠性(请注意TCP可靠性),而无需进行所有来回闲聊以丢失数据包。的好处是它可以提高网络利用率,但可能适合游戏或流媒体等实时应用。
评论
最终,您可以将这些额外功能描述为与可靠性有关。
–user207421
19年6月29日在23:46
评论
当每个应用程序可以简单地依赖于另一个广泛使用的协议(如TCP)时,为什么每个应用程序都会提供自己的可靠性机制?以及您如何建议在应用程序层实现可靠性而不降低堆栈速度?
“由于UDP标头小于TCP标头,因此我们可以利用数据大小。”这种想法的问题在于,您可能会吃掉带有应用程序层协议标头的许多UDP负载,这会减少UDP负载中的可用数据。 TCP和UDP标头大小之间的差异仅为12个字节。此外,UDP实际上是为小型有效负载而设计的,例如576个字节;请记住,UDP只会丢失数据报,而数据报中的数据越多,丢失数据报时丢失的数据就越多。
程序员尝试并失败使用UDP创建类似TCP的协议时,堆栈溢出现象盛行。经验更丰富的程序员告诉他们放弃它,而只使用TCP。他们都认为自己可以做得更好,但这不太可能。
我知道这不是直接属于您的问题,但是UDP可以做得更好的一个原因是,您只能实现所需的可靠性部分。使用TCP,您可以获得有关订购和交付的可靠性。这意味着TCP在等待重新发送上一条消息时可能会出现打ic。使用UDP,您可以确定所需的只是传递,但是如果有任何消息混乱,您不必等待丢失的消息,只需丢弃它们。人们遇到的陷阱是试图复制100%TCP。在这种情况下,只需使用TCP。