gpt4 book ai didi

计算机网络那些事之MTU篇pt.2

转载 作者:我是一只小鸟 更新时间:2023-06-29 22:31:16 25 4
gpt4 key购买 nike

哈喽大家好,我是咸鱼 。

在 《计算机网络那些事之 MTU 篇 》 中,咸鱼跟大家介绍了 MTU 是指数据链路层能够传输的最大数据帧的大小 。

如果发送的数据大于 MTU,则就会进行分片操作(Fragment);如果小于 MTU,就会在实际数据内容后面添加填充数据(Padding),使得数据包总长度达到最小长度要求 。

TCP 因为是有连接的协议,连接在建立的时候就有 MSS(TCP 报文段中数据部分的最大长度) 的协商,以便在传输过程中进行分片 。

在网络传输的过程中,如果中间设备(例如路由器)的 MTU 比较小,就会 MSS clamping 。

MSS clamping 是一种 TCP 优化技术,用于解决 TCP 数据包在传输过程中可能发生的分片问题 。

它会检查 TCP SYN 包中的 MSS 选项,并将其值与网络链路的 MTU 进行比较 。

如果 MSS 值大于 MTU,就将 MSS 值设置为 MTU 减去 IP 头部和 TCP 头部的长度,从而保证 TCP 数据包的大小不会超过网络链路的 MTU,避免发生 IP 分片 。

在 TCP 连接建立后,双方会根据 MSS 值来控制每个 TCP 数据包的大小,从而保证 TCP 数据包不会超过网络链路的 MTU,提高网络传输的效率 。

但是对于面向无连接的协议(例如 UDP ),这时候该怎么办呢?

我们知道以太网规定 MTU 范围上限为 1500 字节,那么 理论上 UDP 能传输的数据包大小上限为:

MTU(1500) - IP Header(20) - UDP Header(8) = 1472 字节 。

  • 如果 UDP 数据包小于等于1472 个字节,那么正常发送不用分片
  • 如果 UDP 数据包超过 1472 个字节,那么移交网络层进行分片并在接收方进行重组

但我们需要知道的是, UDP 包进行分片的时候不像 TCP 那样每个分片里面都复制一个 Header 。

而是第一个分片有 UDP Header,其余的都没有 。

所以接收方拿到 UDP 分片包之后在传输层就得先进行重组成一个完整的 UDP 包然后才能交给上一层 。

这样就会导致一个问题:如果在传输过程中其中一个 UDP 分片包丢了,造成 UDP 包重组失败,接收方会把整个包给丢掉 。

但是又因为 UDP 没有重传机制,就会导致 UDP 发送方不知道接收方丢了这个包 。

然后发送方就会一直发包,接收方一直丢包 。

所以说最好不要发超过接收方 MTU 大小的 UDP 数据包 。

但面向无连接的 UDP 是怎么知道对方 MTU 的呢?(TCP 有 MSS 协商) 。

为此我在虚拟机上简单做了一个实验 。

  • 环境
    • CentOS 7
  • 服务器 A
    • IP:192.168.149.130
    • MTU:800
  • 服务器 B
    • IP:192.168.149.131
    • MTU:1500

然后用 B 服务器去 ping 服务器 A,发送一个大小为 1500 bytes 的数据 。

                        
                          # -M do 表示不分片
# -p 选项用于指定数据包的内容
# -c 2 指定发送数据包的数量为2
# -s 指定数据包的大小
ping -c 2 -s 1000 -M do -p $(echo -n abcdefghijklmnopqrstuvwxyz | xxd -p)   192.168.149.130

                        
                      

image

结果发现服务器 A 全部接受了,按理说 A 的 MTU 是 800,又因为设置了不分片,应该丢弃这个包才对 。

然后我们用 B 服务器去 ping 服务器 A,发送一个大小为 1600 bytes 的数据 。

发现超出服务器 B 的 MTU (1500)了,又因为不允许分片,导致包不能发出 。

                        
                          ping -c 2 -s 1600 -M do -p $(echo -n abcdefghijklmnopqrstuvwxyz | xxd -p)   192.168.149.130

                        
                      

image

跟我想象的不太一样,服务器 A 收到服务器 B 发送的超过自身 MTU 大小的包应该是丢弃,然后回复一个:

                        
                          Type=3 (Destination Unreachable) and code=4, packet too big and DF is set

                        
                      

表示发送方数据包无法到达目的地且无法分片 。

后面我查了一下,应该是本地环境即两个虚拟机之间的网络比较简单,导致网卡能接受这种不合理的包,如果有懂的小伙伴可以私信我 。

但是这个实验至少证明了一点:即 服务器不会去关心对方的 MTU,只会根据自己的 MTU 去进行分片 。

然后我又查阅了大量的资料,我看到一个比较贴切的答案就是:

我们来看下上面这段内容,可以得出 。

在 RFC 中, Internet (IPv4) 标准规定 MTU 最小是 576 bytes 。

所以对于 UDP 来讲,能发的有效数据(Payload)只要不超过 508 bytes 。

576 bytes (MTU) - 60 bytes (IP header 20 bytes + IP option 0-40 bytes) - 8 bytes (UDP Header)= 508 bytes 。

image

我管你服务器的 MTU 是多少,我只发送全世界最小的二层包,总没问题了吧?

很多情况下 IP header 是达不到 60 bytes的,所以一般 UDP 的 Payload 也会是是 512 bytes 。

总结一下:

  • 不同于 TCP ,UDP 这个简单的协议并不关心对方的 MTU 这些问题;如果你要基于 UDP 实现一个协议,就要自己处理超过 MTU 的问题
  • 为了避免分片问题,UDP 只发不超过 IPV4 MTU 范围下限(576 bytes)的包(即 UDP 数据包的最大 Payload 是 512 字节
  • 上述讨论针对的是 IPV4,而非 IPV6

Beej's Guide to Network Concepts 。

domain name system - Why DNS through UDP has a 512 bytes limit? - Server Fault 。

MTU 和 UDP (以及基于 UDP 的协议) | 卡瓦邦噶! (kawabangga.com) 。

最后此篇关于计算机网络那些事之MTU篇pt.2的文章就讲到这里了,如果你想了解更多关于计算机网络那些事之MTU篇pt.2的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com