乐趣区

关于网络编程:小菜学网络MTU

不同的以太网接入设施,一帧能传输的数据量是有差别的。

一般的以太网卡,一帧最多可能传输 1500 字节的数据;而某些虚构设施,传输能力要打些折扣。此外,链路层除了以太网还有其余协定,这些协定中数据帧传输能力也有差别。

最大传输单元

如果待发送的数据超过帧的最大承载能力,就须要先对数据进行分片,而后再通过若干个帧进行传输。

上面是一个典型例子,待发送的数据总共 4000 字节,假如以太网设施一帧最多只能承载 1500 字节。很显著,数据须要划分成 3 片,再通过 3 个帧进行发送:

换句话讲,咱们须要晓得接入设施一帧最多能发送多少数据。这个参数在网络畛域被称为 最大传输单元 (maximum transmission unit ),简称 MTUMTU 形容链路层可能传输的最大数据单元。

查看、设置 MTU

咱们晓得,在 Linux 零碎能够用 ifconfig 或者 ip 这两个命令来查看网卡信息,其中包含 MTU

接下来,咱们关上 docker 进入 netbox 环境进行演示:

docker run --name netbox --rm -it --privileged --cap-add=NET_ADMIN --cap-add=SYS_ADMIN -v /data -h netbox fasionchan/netbox:0.5 bash /script/netbox.sh

先以 ifconfig 命令为例:

root@netbox [~]  ➜ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.2  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 5a:ff:7e:28:81:bc  txqueuelen 1000  (Ethernet)
        RX packets 24  bytes 2165 (2.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 27  bytes 2164 (2.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ip 命令也能够,咱们更举荐应用这个:

root@netbox [~]  ➜ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/tunnel6 :: brd ::
6: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 5a:ff:7e:28:81:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0

咱们能够用 ip 命令,来批改 eth0MTU,以批改 eth0 网卡 MTU 为例:

root@netbox [~]  ➜ ip link set eth0 mtu 68

不同的接入设施,反对的 MTU 范畴不一样。如果咱们将 MTU 设置得太小,设施将报错:

root@netbox [~]  ➜ ip link set eth0 mtu 40
Error: mtu less than device minimum.

MTU 对发送环节的影响

咱们以两台用网线间接相连的主机作为试验环境,来察看网卡 MTU 对发送、接管以太网帧的影响:

试验环境同样通过 docker 来启动:

docker run --name mtu-lab --rm -it --privileged --cap-add=NET_ADMIN --cap-add=SYS_ADMIN -v /data -h mtu-lab fasionchan/netbox:0.5 bash /script/cable-lab.sh

咱们将 ant 主机 eth0 网卡的 MTU 设置成 68,发现数据大于 68 字节的以太网帧将无奈发送:

root@ant [~]  ➜ ip link set eth0 mtu 68
root@ant [~]  ➜ sendether -i eth0 -t 32:65:21:d3:01:2f -d 'hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!'
Fail to send ethernet frame: : Message too long

MTU 复原为默认值 1500 当前,能够胜利发送:

root@ant [~]  ➜ ip link set eth0 mtu 1500
root@ant [~]  ➜ sendether -i eth0 -t 32:65:21:d3:01:2f -d 'hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!'

这就是 MTU 对发送环节的影响:如果数据量大于 MTU,则无奈通过单个以太网帧发送进来,只能以 MTU 为单位对数据进行分片,再封装成若干个帧进行发送。

MTU 对接管环节的影响

那么,_MTU_ 对接管环节有什么影响呢?

咱们将 bee 主机 eth0 网卡的 MTU 设置成 68,并启动 tcpdump 进行抓包:

root@ant [~]  ➜ ip link set eth0 mtu 68
root@ant [~]  ➜ tcpdump -ni eth0

接着,咱们在主机 ant 上,向主机 bee 发送一个数据大于 68 字节的以太网帧:

root@ant [~]  ➜ sendether -i eth0 -t 32:65:21:d3:01:2f -d 'hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!'

然而,主机 ant 上的 tcpdump 程序通知咱们,_eth0_ 网卡并没有收到这个帧!由此可见,以太网帧数据长度一旦大于接管设施 MTU,将被抛弃。

论断

  • 待发送以太网帧数据长度大于发送设施 MTU,则无奈发送;
  • 待接管以太网帧数据长度大于接管设施 MTU,则无奈接管;

【小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注:

退出移动版