📅  最后修改于: 2023-12-03 15:12:15.424000             🧑  作者: Mango
在计算机网络中,MTU(最大传输单元)是指一个通信协议的数据包能够传输的最大长度,通常以字节为单位。MTU 的大小是由链路层和网络层共同协商决定的,但在某些情况下,需要进行路径 MTU 发现,以确定路径上能够正常传输的最大 MTU 大小。
首先,我们需要知道,当 TCP/IP 协议栈在发送数据报时,IP 层会对数据报进行分片(fragmentation),将其分成若干个 MTU 以下的小数据包进行传输,然后再在接收端重新组装。这个过程较为费时、占用带宽,而且可能会造成 IP 包重组失败,从而导致数据丢失。
为了避免这个问题,TCP/IP 协议栈需要限制每个数据报的大小,以尽量避免分片。而这个大小等于路径上能够正常传输的最大 MTU 大小减去 IP 头的长度和 TCP 头的长度,也就是说:
数据报大小 ≤ 最大 MTU - IP 头长度 - TCP 头长度
如果我们能够确定路径上能够正常传输的最大 MTU 大小,就可以避免分片问题,提高传输效率。
路径 MTU 发现就是一种通过探测路径上的 MTU 大小来确定最大 MTU 大小的技术。这个过程大致如下:
在 Python 中,我们可以使用scapy
库来编写路径 MTU 发现的代码。下面是一个简单的示例:
from scapy.all import *
# 目的地 IP 地址
dst = "www.google.com"
# Ping 命令的负载内容,可以根据需要修改
payload = b"ABCDEFGHIJKLMNOPQRSTUVWXYYZ"
# 发送 IP 数据包,探测路径上的 MTU 大小
for i in range(1400, 1500):
p = IP(dst=dst, flags="DF")/ICMP()/Raw(load=payload)
send(p, verbose=False, mtu=i)
time.sleep(0.1)
我们可以通过逐渐递增数据包的大小,来探测路径上的 MTU 大小。当程序输出结果时,我们可以找到一个 MTU 大小,其后的数据包开始出现“ICMP需要分片”的错误,就可以确定路径上能够正常传输的最大 MTU 大小了。
详细的代码和运行结果可以参考这个代码片段。