networking - 在 UDP 的情况下,MTU 重传如何工作

标签 networking tcp network-programming udp mtu

众所周知,UDP 不支持重传和其他一些东西。

我们也知道像 MTU 这样的东西基本上以下列方式工作——当源点和目标点之间的路径上的网络设备之一不支持某种大小的数据包时,它就会丢弃它。

对于 TCP,这不是问题——它已经知道握手后的 MSS 总是小于 MTU(我说的对吗?),因此不可能发送大小大于 MTU 的数据包。

但是,我想知道在 UDP 情况下它是如何工作的?正如我已经说过的,此协议(protocol)中没有重传,也没有 MSS 这样的东西。那么当数据包因超过 MTU 而被丢弃时会发生什么?

或者它只是因为 MTU 性质才起作用(它实际上属于 IP 层,而不是像 UDP 或 TCP 这样的传输层协议(protocol))?所以 IP 层以更小的单元重建丢弃的数据包并再次发送?

最佳答案

首先要区分本地MTU,也就是本地链路的MTU,和路径MTU(PMTU),也就是本地链路的最小MTU。考虑以下拓扑:

    1500       1480       1500
A -------- B -------- C -------- D

那么A的本地MTU是1500,但是PMTU只有1480。

当路由器 B 收到需要转发的大小为 1500 的数据包,并且设置了 DF 位时,它会将下一跳的 MTU(在本例中为 1480)的 ICMP 数据包发送回发送方。然后发送方可以减小数据包大小。

在 TCP 中,这是由网络堆栈透明地完成的。在 UDP 中,应用程序需要处理它。可以通过三种方式做到这一点:

  1. 始终发送足够小的数据包; 1024 在 IPv6 上总是安全的,而 512 通常(但不总是)在 IPv4 上安全;

  2. 使用已连接的 UDP 套接字,并通过减小数据包大小来应对 EMSGSIZE 错误;或

  3. 使用任何类型的 UDP 套接字,请求 PMTU 辅助数据,并使用提供的数据。

技术(3)是最有效的。对于 IPv6,在 Section 11.3 of RFC 3542 中进行了描述.

关于networking - 在 UDP 的情况下,MTU 重传如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38817837/

相关文章:

python - 如何查看 Python 中是否有可用且事件的网络连接?

networking - Docker 容器无法解析对另一个容器中的服务的请求

c++ - 如何调用复合模块的参数?

network-programming - LAN 上的网络发现,无需广播

linux - 为什么epoll_wait(),在5s~10s后返回,TCP连接超时

android - 从网络设备的 IP 地址列表中查找打印机 IP 地址

c - 这部分代码在做什么?

python - TCP 套接字绑定(bind)超时

c# - Android客户端与.Net C#服务器之间的最佳通信策略

java - Java 中的简单网络聊天