【问题标题】:UDP vs TCP, how much faster is it? [closed]UDP vs TCP,它快多少? [关闭]
【发布时间】:2010-09-08 01:18:33
【问题描述】:

用于一般协议消息交换,可以容忍一些丢包。 UDP 比 TCP 效率高多少?

【问题讨论】:

  • 你也可以添加“tcp”标签,因为问题也是关于 TCP 的。
  • “通用协议消息交换”是什么意思?这个问题需要澄清什么是效率。我们是否希望减少小消息的延迟?或者,我们是否希望为连续的数据流提供更高的吞吐量?
  • 除了速度之外,Tcp 比 UDP 有更多更好的功能。
  • TCP 与 UDP 速度的问题没有实际意义。您标题中的问题实际上与问题的主体不匹配。 TCP 和 UDP 数据包在同一介质上以完全相同的速度传输。
  • BBR、FEC、梯度上升/下降都是编程和数学的一部分——常见的让我们明智地理解这一点——这个问题需要编辑,但它非常相关,本质上是一个很好的问题。

标签: networking tcp udp


【解决方案1】:

人们说 TCP 给您的主要好处是可靠性。但事实并非如此。 TCP 为您提供的最重要的东西是拥塞控制:您可以在 DSL 链路上运行 100 个 TCP 连接,所有这些连接都以最大速度运行,并且所有 100 个连接都将是高效的,因为它们都“感知”了可用带宽。尝试使用 100 个不同的 UDP 应用程序,所有应用程序都尽可能快地推送数据包,看看效果如何。

在更大的范围内,这种 TCP 行为是防止 Internet 陷入“拥塞崩溃”的原因。

倾向于将应用程序推向 UDP 的因素:

  • 群组交付语义:可以比 TCP 的点对点确认更有效地向一群人进行可靠交付。

  • 乱序交付:在很多应用程序中,只要您获取所有数据,您就不需要关心它是按什么顺序到达的;您可以通过接受无序块来减少应用程序级延迟。

  • 不友好:在 LAN 聚会上,您可能不在乎您的网络浏览器是否能正常运行,只要您尽可能快地向网络发送更新即可。

但即使您关心性能,您也可能不想使用 UDP:

  • 您现在正处于可靠性的困境中,您为实现可靠性所做的许多事情最终都可能比 TCP 已经做的要慢。

  • 现在您对网络不友好,这可能会导致共享环境出现问题。

  • 最重要的是,防火墙会阻止你。

您可以通过将多个 TCP 连接“中继”在一起来潜在地克服一些 TCP 性能和延迟问题; iSCSI 这样做是为了绕过局域网上的拥塞控制,但您也可以这样做来创建一个低延迟的“紧急”消息通道(TCP 的“紧急”行为完全被破坏了)。

【讨论】:

  • 好答案,我什至会更笼统地说“流量控制”(与拥塞控制相反,它是流量控制的一个子集)。不仅多个 TCP 连接可以共享一个链接,而且如果发送方出于任何原因暂停处理传入数据,它还可以防止发送方溢出接收方的缓冲区。
  • @AaronLS:丢包RTT(往返时间)增加(可以看作是排队延迟 i>) 是/可以是(例如:WiFi 网络可能会在没有真正拥塞的情况下丢失数据包,欺骗一些 TCP 拥塞控制算法来避免拥塞)拥塞指标。
  • UDP 是一个难以处理的混蛋……我已经对此感到筋疲力尽了。无论我做什么,我似乎都无法在性能、延迟、吞吐量和可靠性之间找到平衡点。非常适合实时的事情,比如计时器上的事情……但我正在使用 UDP 和前向纠错来替换 TCP,这比我想象的要困难得多。拥塞控制。在 1GB 网络和无线网络上运行的通用系统都是一件艺术品。我觉得我正在尝试重新组装装入霰弹枪的数据包。
  • 顺便说一句,TCP 的另一个优点是它本质上是面向连接的,这极大地简化了应用程序客户端处理逻辑(listen -> accept -> 客户端状态自然独立于其他客户端)。使用 UDP 处理来自单个客户端的多个连接尤其困难。对 UDP 有利的一点是 UDP 堆栈真的易于实现,这对嵌入式系统(微控制器、FPGA 等)来说是一个巨大的优势,特别是 FPGA 的 TCP 实现通常是你所需要的只是想从别人那里购买而不考虑)。
  • 这一切都只是假设我们对交付大量数据感兴趣(不太关心延迟)。在相当多的应用程序(游戏/VoIP)中,情况截然不同:我们有 very_small 量的数据,但确实非常关心延迟;正是这个简单的东西占了 UDP 合法使用的 99%。还有一些挑剔的:(a)团体交付不能在 Internet 上工作(而且不太可能),所以它是仅限 Intranet 的领域; (b) 根据 Google,只有 8-9% 的互联网人口存在 UDP 问题;(c) “网络不友好”不适用于固定速率流
【解决方案2】:

在某些应用程序中,TCP 比 UDP 更快(更好的吞吐量)。

在执行大量相对于 MTU 大小的小写入时会出现这种情况。例如,我阅读了一个实验,其中通过以太网(1500 字节 MTU)发送 300 字节数据包流,TCP 比 UDP 快 50%

原因是因为 TCP 会尝试缓冲数据并填充整个网段,从而更有效地利用可用带宽。

另一方面,UDP 将数据包立即传送到网络上,从而使网络因大量小数据包而拥塞。

除非您有非常具体的原因,否则您可能不应该使用 UDP。特别是因为您可以通过禁用Nagle algorithm 为 TCP 提供与 UDP 相同的延迟(例如,如果您正在传输实时传感器数据并且您不担心大量小数据包会阻塞网络)。

【讨论】:

  • 我实际上已经为此做了基准测试。我正在发送与 UDP 一样大的数据包,而不会引发异常(在 Java 中),而且 TCP 速度要快得多。我猜很多操作系统、驱动程序和硬件优化也是其中的一部分。
  • @Myforwik:首先,这不是实现定义的,它是 TCP 协议的一部分。它被称为 Nagle 算法。它有助于预防所谓的傻窗综合症。查找这两个术语。其次,没有来自 TCP 的 pov 的数据包的概念。最后,“Effective TCP/IP Programming”一书用一整章来介绍这个主题,而其他多个章节则专门用于了解何时使用 TCP 与 UDP 的相关主题。我提出这种情况(这实际上很常见)是因为 OP 提出了一个一般性问题,这是许多可能的答案之一。
  • @Myforwik。当向他人暗示白痴时,请尝试意识到我们所有人的知识都存在差距——包括你在内。毕竟,SO 是一个知识共享的论坛。几乎所有第一人称射击游戏都使用 UDP,而且他们很少发送大小接近 MTU 的数据包。如果您想向 John Carmack 建议他想出这种方法是多么愚蠢,我鼓励您首先在这方面彻底教育自己。 15 年,一个行业价值的高性能网络代码不会因为你认为它“愚蠢”而躺下死亡。
  • "我读过一个实验,其中通过以太网(1500 字节 MTU)发送 300 字节数据包流,TCP 比 UDP 快 50%。" - 可以你链接这个实验?
  • @Leviathan 在《Effective TCP/IP Programming》一书中。
【解决方案3】:

UDP 比 TCP 快,原因很简单,因为它不存在允许连续数据包流的确认数据包 (ACK),而不是确认一组数据包的 TCP,通过使用 TCP 窗口大小和轮数计算得出-行程时间(RTT)。

更多信息,我推荐简单但非常容易理解的Skullbox explanation (TCP vs. UDP)

【讨论】:

  • 实际上在很多情况下 TCP 实际上比 UDP 快。请参阅下面的答案。
  • 哪个更快完全取决于流量特征。
  • 虽然答案可能是正确的,但它并没有回答问题,而是反复重复其他地方提到的知识。也没有提到带有 ACK 的可靠 UDP 方法可以明显比 TCP 快。
  • 为什么额外的 ACK 会使 TCP 变慢?从接收方的角度来看,一旦数据包到达,它就会传递给应用程序并发送 ACK。这不像是应用在等待服务器确认确认。
【解决方案4】:

具有容错性

你的意思是“有损失容忍度”吗?

基本上,UDP 不是“容错”的。您可以向某人发送 100 个数据包,但他们可能只会收到其中的 95 个数据包,而且有些数据包的顺序可能错误。

对于像视频流和多人游戏这样的事情,最好是错过一个数据包而不是延迟它后面的所有其他数据包,这是显而易见的选择

但对于大多数其他事情,丢失或“重新排列”的数据包至关重要。您必须编写一些额外的代码才能在 UDP 之上运行,以便在遗漏时重试,并强制执行正确的顺序。这会在某些地方增加一点开销。

谢天谢地,一些非常非常聪明的人已经做到了这一点,他们称之为 TCP。

这样想:如果一个数据包丢失,您是希望尽快获取下一个数据包并继续(使用 UDP),还是您真的需要丢失的数据(使用 TCP)。除非您处于非常极端的情况,否则开销无关紧要。

【讨论】:

  • 100 个数据包中有 5 个数据包?这是相当多的。我想这只是一个例子。问题:在实际情况下会丢失多少个数据包?因为如果它是例如万分之二(加负1),那我就不用担心了。
  • @freakish,是的,这只是一个例子。实际丢包量取决于你的连接,上游网络等。我以前玩过很多网络游戏,我发现如果只是我使用互联网连接,我不会丢包,但是一旦我启动后台下载,我就会开始下载一些(可能是 10%-20%)。不过这是大约 5 年前的事了,更快的互联网连接可能会有所帮助。
  • Internet 路由器在 tcp 之前丢弃 udp
【解决方案5】:

当谈到“更快”时 - 至少有两个非常不同的方面:吞吐量和延迟。

如果谈到 吞吐量 - TCP 的流量控制(如其他答案中所述)非常重要,并且通过 UDP 做任何可比的事情,虽然当然可能,但将是一个大头痛(tm)。因此 - 当您需要吞吐量时使用 UDP 很少被认为是一个好主意(除非您想获得相对于 TCP 的不公平优势)。

但是,如果谈到 延迟 - 整个事情就完全不同了。虽然在没有数据包丢失的情况下,TCP 和 UDP 的行为非常相似(任何差异,如果有的话,都是微不足道的)——在数据包丢失之后,整个模式发生了巨大的变化。

在任何数据包丢失后,TCP 将等待重新传输至少 200 毫秒(根据 RFC6298 的第 2.4 段为 1 秒,但实际的现代实现倾向于将其减少到 200 毫秒)。此外,使用 TCP,即使是那些确实到达目标主机的数据包 - 在收到丢失的数据包之前也不会被传递到您的应用程序(即整个通信延迟约 200 毫秒) - 顺便说一句,这种效果,称为 Head-of -线路阻塞是所有可靠有序流所固有的,无论是 TCP 还是可靠+有序 UDP。更糟糕的是——如果重传的数据包也丢失了,那么我们将讨论大约 600 毫秒的延迟(由于所谓的指数退避,第一次重传是 200 毫秒,第二次是 200*2=400 毫秒)。如果我们的频道有 1% 的丢包率(按照今天的标准,这还不错),并且我们有一个每秒更新 20 次的游戏 - 这样的 600 毫秒延迟将平均每 8 分钟发生一次。因为 600 毫秒足以让你在快节奏的游戏中丧命 - 嗯,这对游戏玩法非常不利。这些影响正是游戏开发者通常更喜欢 UDP 而不是 TCP 的原因。

但是,当使用 UDP 来减少延迟时 - 重要的是要意识到仅仅“使用 UDP”不足以显着改善延迟,这完全取决于您如何使用 UDP。特别是,虽然 RUDP 库通常避免“指数退避”并使用更短的重传时间——如果它们被用作“可靠的有序”流,它们仍然必须遭受行头阻塞(所以在双丢包,而不是 600 毫秒,我们将得到大约 1.5 * 2 * RTT - 或者对于一个相当不错的 80 毫秒 RTT,这是一个约 250 毫秒的延迟,这是一个改进,但仍然可以做得更好)。另一方面,如果使用http://gafferongames.com/networked-physics/snapshot-compression/ 和/或http://ithare.com/udp-from-mog-perspective/#low-latency-compression 中讨论的技术,则可以完全消除线头阻塞(因此对于每秒更新 20 次的游戏的双包丢失,无论 RTT 如何,延迟都是 100 毫秒)。

附带说明 - 如果您碰巧只能访问 TCP 而没有 UDP(例如在浏览器中,或者如果您的客户端位于阻止 UDP 的 6-9% 的丑陋防火墙之一之后)- 似乎是一种实现 UDP-over-TCP 而不会产生太多延迟的方法,请参见此处:http://ithare.com/almost-zero-additional-latency-udp-over-tcp/(请务必阅读 cmets(!))。

【讨论】:

    【解决方案6】:

    哪种协议性能更好(在吞吐量方面) - UDP 或 TCP - 实际上取决于网络特性和网络流量。例如,Robert S. Barnes 指出了 TCP 性能更好的场景(小型写入)。现在,考虑一个网络拥塞并且同时具有 TCP 和 UDP 流量的场景。网络中使用 TCP 的发送者将感知“拥塞”并降低其发送速率。但是,UDP 没有任何拥塞避免或拥塞控制机制,使用 UDP 的发送者将继续以相同的速率泵入数据。逐渐地,TCP 发送者将他们的发送速率降低到最低限度,如果 UDP 发送者有足够的数据通过网络发送,他们将占用大部分可用带宽。因此,在这种情况下,UDP 发送者将拥有更大的吞吐量,因为他们获得了更大的网络带宽蛋糕。事实上,这是一个活跃的研究课题——如何在存在 UDP 流量的情况下提高 TCP 吞吐量。据我所知,使用 TCP 应用程序可以提高吞吐量的一种方法是打开多个 TCP 连接。这样,即使每个 TCP 连接的吞吐量可能受到限制,所有 TCP 连接的吞吐量总和也可能大于使用 UDP 的应用程序的吞吐量。

    【讨论】:

    • 这是不正确的,路由器会在 TCP 之前丢弃 UDP。在共享线路上,您可能会被 UDP 淹没,但在供过于求的情况下可能发生的情况取决于技术,但 UDP 很容易降级到几乎不会发送冲突的地步。
    • 我喜欢你的解释,但没有得到一分。如果 UDP 连接可以获取所有流量(如果带宽低或数据高),那么在这种情况下,如果使用 TCP,您的应用程序基本上会受制于使用 UDP 的应用程序。如果所有应用程序都使用 TCP,那么它们彼此“玩得很好”。那为什么首先要在路由器上允许 UDP 呢?
    • @PSIXO:嗯,TCP 和 UDP 服务于不同的应用程序需求,因此两者都被应用程序使用。您的建议的含义是,我们应该为 TCP 和 UDP 流量使用不同的网络基础设施——这是一个昂贵的提议,而且我们现在当然不能做,尤其是在所有投资已经完成的情况下。这就是为什么研究人员忙于寻找平衡“软件”冲突的替代方法。
    • 嗯,基本上是的,拥有两个基础设施将是一个完美的解决方案,但不幸的是,这并不合理。我想用我的评论说的是你夸大了 UDP 对 TCP 的影响,因为如果这是一个很高的因素,如果他们需要 TCP 快速运行,人们只会在路由器上禁用 UDP(就像他们有时在公司中所做的那样)。还要记住,UDP 数据包比 TCP 更有可能被丢弃。关于您回答中的其他事实,我完全同意并认为这很有帮助,但我只是认为您高估了某些影响。
    【解决方案7】:

    每个 TCP 连接都需要在传输数据之前进行初始握手。此外,TCP 标头包含大量用于不同信号和消息传递检测的开销。对于消息交换,如果可以接受很小的失败概率,UDP 可能就足够了。如果必须验证收据,TCP 是您的最佳选择。

    【讨论】:

    • 失败的可能性很小并且对数据包大小有限制。
    【解决方案8】:

    我会把事情说清楚。 TCP/UDP 是两辆正在路上行驶的汽车。假设交通标志和障碍物是错误 TCP 关心交通标志,尊重周围的一切。慢速驾驶,因为汽车可能会出事。虽然 UDP 只是开车,全速不尊重路标。没什么,一个疯狂的司机。 UDP 没有错误恢复功能,如果有障碍物,只会与障碍物发生碰撞,然后继续。而 TCP 确保所有数据包都被完美地发送和接收,没有错误,因此,汽车只是通过障碍物而不会发生碰撞。我希望这是一个很好的例子让你理解,为什么 UDP 在游戏中是首选。游戏需要速度。 TCP 优先用于下载,否则下载的文件可能已损坏。

    【讨论】:

    • 要明确:“所有数据包都被完美地发送和接收”是一个非常糟糕的夸张。由于 TCP 只有 16 位校验和,因此 TCP 未检测到的错误比应有的要频繁得多。事实上,在下载仅 1G 的文件时(通过特别糟糕的连接)也有可能看到此类错误。
    【解决方案9】:

    根据我的经验,UDP 会稍微快一些,但不会快很多。选择的不应该是性能,而是消息内容和压缩技术。

    如果它是带有消息exchange 的协议,我建议您使用 TCP 对性能造成的轻微影响是值得的。您将获得两个端点之间的连接,这将为您提供所需的一切。不要尝试在 UDP 之上制造自己的可靠双向协议,除非您对自己的工作非常非常有信心。

    【讨论】:

      【解决方案10】:

      请记住,TCP 通常在线上保留多条消息。如果你想在 UDP 中实现这一点,如果你想可靠地做到这一点,你将做很多工作。您的解决方案要么变得不那么可靠、不那么快,要么工作量大得惊人。有 UDP 的有效应用程序,但如果您要问这个问题,您的问题可能不是。

      【讨论】:

        【解决方案11】:

        已经做了一些工作,让程序员可以同时享受这两个世界的好处。

        SCTP

        它是一个独立的传输层协议,但它可以用作一个库,在 UDP 之上提供额外的层。通信的基本单元是消息(映射到一个或多个 UDP 数据包)。内置拥塞控制。该协议有旋钮和旋钮可以打开

        • 按顺序传递消息
        • 使用用户定义的参数自动重新传输丢失的消息

        如果您的特定应用程序需要这些。

        其中一个问题是连接建立是一个复杂的过程(因此过程缓慢)

        其他类似的东西

        另一个类似的专有实验性东西

        这也试图改进 TCP 的三次握手,并改变拥塞控制以更好地处理快速线路。

        【讨论】:

          【解决方案12】:

          如果您需要通过网络在两个尚未通话的 IP 之间快速发送消息,那么 UDP 的到达速度至少要快 3 倍,通常要快 5 倍。

          【讨论】:

          • 任何参考资料?
          • UDP 的到达速度会快 3 到 5 倍——或者根本不会到达。 ;-)
          • 任何可靠来源的“至少快 3 倍”屏幕
          • 好的,我想重新回答这个问题,我会告诉你原因 - 如果你做对了,UDP 会快很多。
          【解决方案13】:

          不考虑网络情况,谈 TCP 或 UDP 是没有意义的。 如果两点之间的网络质量非常高,UDP 绝对比 TCP 快,但在其他一些情况下,例如 GPRS 网络,TCP 可能比 UDP 更快,更可靠。

          【讨论】:

            【解决方案14】:

            网络设置对于任何测量都至关重要。如果您通过本地计算机上的套接字或与世界的另一端进行通信,这会产生巨大的差异。

            我想在讨论中添加三件事:

            1. 您可以在here 中找到一篇关于 TCP 与 UDP 的非常好的文章 游戏开发的背景。
            2. 此外,iperfjperf 使用 GUI 增强 iperf)是 非常好的工具,可以通过测量自己回答您的问题。
            3. 我在 Python 中实现了一个基准测试(请参阅this SO question)。对于 UDP,平均 10^6 次迭代发送 8 个字节的差异约为 1-2 微秒。

            【讨论】:

            • 要使基准测试与现实世界的互联网相关,您需要使用 netem 等丢包模拟器重新运行它。如果操作正确(模拟 RTT 为 100 毫秒,模拟丢包率为 1%),结果将大不相同。简而言之 - 虽然 TCP 和 UDP 延迟对于零丢包确实是相同的 - 但对于每个丢包,它们开始有很大的不同。
            猜你喜欢
            • 2018-03-18
            • 1970-01-01
            • 2014-01-23
            • 2011-05-30
            • 2016-07-08
            • 1970-01-01
            • 2019-09-09
            • 2014-03-08
            • 2012-06-20
            相关资源
            最近更新 更多