不知道你第一次看到二层的MTU和三层TCP的MSS有没有这样一个困惑,既然网络层已经可以通过MTU进行拆包了那为什么传输层还要一个MSS呢?反正我一开始的时候是困惑的。
为了说明今天的问题,先来解释一下MTU和MSS是什么。
MTU
MTU(Maximum Transmission Unit)最大传输单元,是数据链路层能够传输的最大字节数,一般情况下是1500字节,我们可以通过ifconfig或者ip addr命令来查看,如下:
# ip addr
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
...
可以看到mtu 1500,这个就表示我这台机器二层(数据链路层)允许通过的最大数据是1500字节。那为什么是1500字节呢?这个似乎没有一个官方的说法,但我们可以推测一下。假如我们随便取个数,比如200,我们知道IP头是20字节(假设没有option的情况下, 另外IPv6的IP头是40字节,这里不考虑IPv6的情况),实际传输的数据就是200字节-20字节IP头-20字节TCP头=160字节,有效传输比就是 160/200 = 80%,而如果是1500字节,有效传输比就是(1500-20-20)/1500=97%。所以,之所以设置成1500字节应该是为了有效传输率考虑的。
我们也可以手动修改MTU的大小,例如:
root@debian:~# ip link set eth0 mtu 1400
# 或者
root@debian:~# ifconfig eth0 mtu 1500 up
这里面有几个细节要注意:
1.MTU不包含数据链路层的头
这是因为MTU是链路层的限制,而拆包发生在IP层,这个时候还没有到数据链路层,也就还没有数据链路层的头了,这个过程也符合代码编写的习惯,先判断数据是否符合要求,再决定是发送还是报错。
2. MTU并不是越