如果你实现了自己的错误检查,为什么要使用TCP而不是UDP呢?

7

我在网上看了很多关于为什么要使用UDP或TCP的东西,但我仍然需要帮助理解一些内容。

如果我在应用程序中实现了错误检查和重传,为什么我甚至还考虑使用TCP呢?难道利用TCP内置功能比在应用程序层面上自己实现这些功能更加方便开发人员吗?我知道TCP包括流量控制,这使它对网络上的其他服务更加友好,但是,如果我只关心自己的应用程序尽可能快速,那么我不是应该在每种情况下选择UDP吗?

重新实现TCP功能在你的应用程序中是一个值得考虑的工作吗?我只需要帮助理解为什么,如果UDP如此快速,为什么每个应用程序都不在任何情况下使用UDP。


1
除了用于建立TCP连接的最初3个数据包之外,这两者之间没有太大的区别。有效载荷往往比数据包头部的大小要大得多。 - Phylogenesis
很有趣。所以你的意思是在应用程序中实现TCP功能的开销通常不值得努力?但是难道不是BitTorrent开始使用UDP而不是TCP,因为它更“快”吗? - red888
1
当你比较在UDP流中实现自己的重新排序/重传/流量控制的开销时,不需要。UDP真正适用于“发射并忘记”的情况。 - Phylogenesis
4个回答

6
TCP不仅提供错误检查,如果您想替换它,需要实现很多东西。以下是一些无特定顺序的想法: 1. 标准化 您编写了自己的传输协议。恭喜!但由于只有您一个人在使用,所以只能和自己玩耍。而TCP已经存在并在任何平台上得到了充分测试。它受防火墙、代理、路由器和网络中可能遇到的其他所有内容的支持。 2. 拥塞控制 这里所说的“流量控制”(见下一条)是指拥塞控制,它会在网络拥塞时对TCP流进行限制。但是你是个自私的人(没关系!),所以你会问为什么要关心拥塞控制。那么,你大部分网络使用的瓶颈是你和服务提供商之间的链接。你的服务提供商通常会有充足的资源和网络工程师。这些人知道如何保护网络不被过度使用并避免热点问题。因此,TCP的拥塞控制实际上是最大程度地保护了你和你的应用程序,确保单个应用程序不能占用整个连接。它有助于确保你不会做出愚蠢的事情,比如只因为你的PC到路由器的链接支持1Gbps就发送价值1Gbps的流量到50Mbps的连接中。

3. 流量控制

流量控制并非拥塞控制。简而言之,流量控制是在您无法处理传入信息时告诉对方停止发送。想象一下移动电话试图从附近的HTTP服务器加载一个重的网页。服务器可以在短时间内将整个页面倾泻到网络上,而手机处理它需要更长的时间。在这种情况下,瓶颈不是网络,而是其中的某个设备。您的TCP替代方案也必须解决此问题。
4. 按顺序交付
除了错误检测外,TCP保证数据按正确顺序到达。这与错误检测不同,它是一项额外的功能。
5. 安全性
TCP三次握手以及现代操作系统生成初始序列号的方式几乎保证了双方对方的IP地址是真实的,而不是伪造的。这并不总是这样。当初始序列号容易预测时,存在这些攻击。
此外,实现TCP的所有功能很难,而且复杂性会导致错误。许多TCP实现已知包含各种漏洞,例如缓冲区溢出,其中一些漏洞具有严重的安全影响。希望现在已经找到并修复了所有这些问题。新协议和新实现总是存在引入新安全漏洞的风险。
6. 性能
网络卡和现代操作系统已经很好地承担了管理TCP的负载。你想使用自己的序列号和错误检测?你必须在用户空间中自己实现它们(并承受性能损失,特别是如果你的应用程序是用像Java这样的语言编写的),或者准备编写内核和驱动程序补丁。
此外,现有的TCP实现已经被整整一代工程师审查和优化过了。要创建一些像它们一样精细的东西将非常具有挑战性。

我喜欢这个答案,因为你涵盖了TCP的每一个特性。我之前没有考虑到,如果没有拥塞控制,实际上可能会对自己造成伤害。但是当你谈到“标准化”时,我有些困惑。我并不是在问如何实现自己的传输层协议,而是指在应用层实现TCP的功能。在这种情况下,只要用户安装了你的应用程序,它就可以工作。你是说由于必须打包额外的功能,所以将其移植到其他平台会更加困难吗? - red888
2
@red888 首先,标准化意味着您不必重新发明轮子,因为这个轮子存在于您可以想象的每个平台上。此外,现在它是一个非常稳定的轮子。其次,使用自定义传输协议是可能的,但这就像用非标准轨距建造铁路一样。只要列车只需要在您的站点之间行驶,它们就可以很好地运行。但是,当您想要将火车发送到其他地方时,您将会遇到问题。 - Malt

3
您可以通过UDP构建自己的类似TCP的协议。Google正在使用QUIC进行尝试,以一种与互联网兼容的方式修复TCP的缺陷,因此只剩下UDP作为底层传输协议。
QUIC的主要创新点包括:
- 多个流。数据包丢失仅会延迟单个流,其他流仍然继续。 - 前向纠错技术可避免在数据包丢失时出现任何停顿。
正如您所看到的,完全可以替代TCP。
但这种方案很可能不值得尝试。QUIC采用的并非是为了提高吞吐量,而是为了降低延迟。预期的使用场景肯定是Web浏览。UDP并不比TCP“快多少”。为什么会呢?TCP和UDP都可以以线路速度运行,减去一些相当小的开销。
另外一种流行的方案是首先将数据发送到UDP上。如果需要重试,则在TCP上重新发送。

OP的问题不是能否替换TCP,而是为什么开发人员选择使用它。 - Malt

1

我只需要帮助理解为什么,如果UDP更快,每个应用程序不都在每种情况下使用UDP。

UDP本身并不更快。它甚至可能会更慢:

  • UDP是基于数据包的,也就是每个send都会产生一个新的带有所有相关开销的数据包。相比之下,TCP是基于流的,并尝试通过合并多个send来创建最佳大小(MTU)的数据包。因此,它通过自动调整实现了更少的开销,而使用UDP需要显式调整才能实现相同的性能。
  • 在数据包丢失时,TCP会减缓发送速度,以便不会丢失更多数据包。使用UDP时,您要么必须保持在线路的最大连接以下以确保安全,要么就必须预计会有大量数据包丢失。当然,您可以实现类似于TCP的方法,或者您可以实现一个更好的方法,该方法不是通用的,但更适合您的用例。
  • 对于短连接,UDP可能更快,因为您没有初始握手。但是,您仍然必须注意数据包丢失,例如SIP(RFC3261)中演示了如何处理这种情况。
  • UDP通常用于实时音视频流传输。但这不是因为它更快,而是因为具有低延迟非常重要,并且所使用的编解码器可以处理数据包丢失。在这种情况下,像TCP一样的数据重传是无用的。
  • 相反,TCP用于可靠地传输大量数据,例如在FTP和HTTP中所做的那样。

1
选择TCP的另一个原因可能是:当您需要通过NAT路由器进行通信时,使用TCP时不必发送太多IP数据包。这是因为在任何协议上,NAT路由器都会在一段时间后(可能是两端都已死亡)丢弃内部和外部网络地址之间的关联。但是,在典型的NAT路由器上,使用TCP超时的时间为几十分钟,而UDP的超时时间为几十秒。这对于移动设备尤其重要,因为每发送一个数据包就会耗费电池电量。因此,许多手机更喜欢使用TCP连接上的SIP协议,而不是使用UDP。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接