
1.IP数据分片之MTU和TCP的MSS

1.1最大传输单元(Maximum Transmission Unit,MTU)
数据链路层传输的帧大小是有限制的,以太网和IEEE 802.3对数据帧的长度都有一个限制,不能把一个太大的包直接塞给链路层,这个限制被称为最大传输单元(Maximum Transmission Unit,MTU)。
以太网的贞最小为64字节,最大为1518字节。除去14字节头部和4字节 CRC字段,最小的有效载荷为46字节,最大的有效载荷为1500字节这个值就是MTU
。就是说传输100KB的数据,至少需要发送69次以太网的贞。
不同的数据链路层的MTU
也是不同的,IP协议的数据报最大为65535
个字节,如果开启了巨型贞(Jumbo Frame)能达到9000
个字节。这远超出了MTU
的值,所以当IP数据报大于MTU的时候就需要对数据进行分片
,这也是IP协议的主要功能之一。
IP首部中有个字段片偏移
,在IP数据报长度大于MTU的时候对数据报进行分片,片偏移用来表示数据报在原来分组的相对位置,以8个字节为偏移单位,如下图:

我们使用ping请求发送3000个字节给www.baidu.com
,网卡eto
的MTU为1500。使用wireshark抓包如下:
- 第一个包

ip.id = 0x00005ce1
ip.flags.mf(More fragments : Set) = 1,代表这个id的ip分组还有更多分片。
ip.frag_offset(Fragment offset:0),代表分片偏移量是0。
ip首部20个字节,1500-20=1480字节。
- 第二个包

ip.id = 0x00005ce1
ip.flags.mf(More fragments : Set) = 1,代表这个id的ip分组还有更多分片。
ip.frag_offset(Fragment offset:1480),代表分片偏移量是0。
ip首部20个字节,1500-20=1480字节。
- 第三个包

ip.id = 0x00005ce1
ip.flags.mf(More fragments : Set) = 2960,代表这是这个ip分组的最后的一个分片,可以进行重组了。
ip首部20个字节,icmp首部8字节,68-20-8=40字节。
ip.id=0x00005ce1的三个分片的载荷加起来正好是3000个字节。
1.2TCP最大报文段长度(Max Segment Size,MSS)
TCP为了避免被发送方分片,它主动把数据分成小段再交给网络层。最大的分段大小称为MSS(Maximum Segment Size
),它相当于把MTU刨去IP头和TCP头之后的大小,所以一个MSS恰好能装进一个MTU中。

有时候TCP的头不止有20个字节,还有可选项会占用一定的MSS空间。这些信息我们都能通过Wireshar观察到。

以太网贞是1500字节+14字节的MAC头,TCP头一共是32个字节,可选项占了12字节。所以TCP的MSS=1500-20-20-12=1448字节。
UDP协议没有MSS的概念,传输层的数据可能一股脑的交给网络层,所以数据可能会被分片而影响性能。
在三次握手的时候接收方和发送方都会声明自己MSS
,因为接收方和发送方的MTU可能是不同的,最终会以较小的MSS
为准。