0%

测试最优MTU的shell脚本

MTU 即最大传输单元(英语:Maximum Transmission Unit),在路由设备上可以设置这个值,选择合适的MTU大小可以优化网络传输速度。

因特网协议允许IP分片,这样就可以将数据报包分成足够小的片段以通过那些最大传输单元小于该数据报原始大小的链路了。这一分片过程发生在 IP 层(OSI模型的第三层,即网络层),它使用的是将分组发送到链路上的网络接口的最大传输单元的值。原始分组的分片都被加上了标记,这样目的主机的 IP 层就能将分组重组成原始的数据报了。
在因特网协议中,一条因特网传输路径的“路径最大传输单元”被定义为从源地址到目的地址所经过“路径”上的所有IP的最大传输单元的最小值。或者从另外一个角度来看,就是无需进一步分片就能穿过这条“路径”的最大传输单元的最大值。
— 摘自维基百科

我写了一个shell脚本,可自动找到你所在网络的最佳MTU大小。

optimized-mtu-size-finder.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash

echo -e "PING PAYLOAD\tRESULT"

ping_address=163.com
ping_header_size=28
payload_size=1500

while true
do
ping $ping_address -M do -s $payload_size -c 1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "$payload_size bytes\tSUCCESS"
break
else
echo -e "$payload_size bytes\tFAILED"
payload_size=`expr $payload_size - 10`
fi
done

while true
do
test_size=`expr $payload_size + 1`
ping $ping_address -M do -s $test_size -c 1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "$test_size bytes\tSUCCESS"
payload_size=$test_size
else
echo -e "$test_size bytes\tFAILED"
break
fi
done

optimized_mtu_size=`expr $payload_size + $ping_header_size`
echo "OPTIMIZED MTU SIZE = $optimized_mtu_size bytes ($payload_size + $ping_header_size)"

我的shell脚本水平不高,不过这个代码足可以说明确定最佳MTU大小的方法了。

首先从1500字节开始以-10递减,直至成功ping通,然后以+1递增,直到ping失败为止。最后一个成功的值加上Ping命令数据包的头大小28字节即是最佳MTU的大小。

我使用电信光线100兆宽带,使用该脚本得到的最佳MTU是1452字节:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ./optimized-mtu-size-finder.sh
PING PAYLOAD RESULT
1500 bytes FAILED
1490 bytes FAILED
1480 bytes FAILED
1470 bytes FAILED
1460 bytes FAILED
1450 bytes FAILED
1440 bytes FAILED
1430 bytes FAILED
1420 bytes SUCCESS
1421 bytes SUCCESS
1422 bytes SUCCESS
1423 bytes SUCCESS
1424 bytes SUCCESS
1425 bytes FAILED
OPTIMIZED MTU SIZE = 1452 bytes (1424 + 28)

我将路由器上的MTU修改为1452,随后在电脑的Arch Linux系统中查找网卡设备名,我的是enp2s0

1
ip link list

将这个网卡的MTU也设置了同样值(不知是否必要~~)。

1
sudo ip link set dev enp2s0 mtu 1452

MTU修改后,确有感觉网络速度提高了些许。