3. IP分片与重组:MTU、分片原理与片偏移计算
聊到IP分片,我得先坦白一件事——刚入行那会儿,我觉得这玩意儿就是个教科书概念,实战中根本用不上。直到有一次,我在一个跨国视频会议项目里,眼睁睁看着大包在中间路由器上被静默丢弃,用户那边画面卡成PPT,我才意识到:不懂分片,你连网络故障都定位不了。
这一节,咱们就把IP分片与重组彻底讲透。说白了,就是IP层怎么把一个大包切碎,到了对端再拼回去。
3.1 MTU——为什么非要分片?
MTU(Maximum Transmission Unit),最大传输单元。它指的是一个网络接口能承载的最大IP数据报长度(不含二层帧头)。
常见的MTU值:
| 链路类型 | MTU(字节) | 备注 |
|---|---|---|
| 以太网 | 1500 | 最常见,绝大多数场景 |
| PPPoE | 1492 | 宽带拨号,比以太网少8字节 |
| FDDI | 4352 | 光纤分布式数据接口 |
| 令牌环 | 4464 | IBM遗留技术 |
| 串行链路(PPP) | 1500(默认) | 可协商 |
为什么要有MTU?因为物理层和数据链路层有传输限制。你想想看,以太网帧的数据段最大就1500字节,IP层要是硬塞一个4000字节的包,网卡直接罢工。
核心原则:IP数据报长度 ≤ 出接口MTU,否则必须分片。
3.2 分片原理——谁来做?怎么切?
分片发生在路由器上,而不是发送端主机。主机只管把数据报扔给下一跳,路由器发现出接口MTU不够大,才会动手切。
分片时,IP头部中的三个字段至关重要:
- 标识(Identification):16位,同一个原始数据报的所有分片共享一个标识值。重组时靠它认亲。
- 标志(Flags):3位,实际只用两位。
- DF(Don't Fragment):置1表示不允许分片。如果遇到超MTU,路由器直接丢包并回送ICMP差错报文。
- MF(More Fragments):置1表示后面还有分片;置0表示这是最后一个分片。
- 片偏移(Fragment Offset):13位,以8字节为单位,表示该分片在原始数据报中的位置。
我个人习惯:抓包时先看Identification字段。同一个值的一串分片,就是一家人。MF位为0的那个,就是家里的老幺。
3.3 片偏移的计算——别被8字节单位绕晕
片偏移的单位是8字节,这是很多初学者栽跟头的地方。为什么是8?因为13位片偏移最多表示8192个偏移单位,乘以8就是65536字节,刚好覆盖IP数据报的最大长度(16位总长度字段)。
计算规则很简单:
- 每个分片的数据部分长度必须是8的整数倍(最后一个分片除外)。
- 片偏移 = 该分片之前的数据字节数 ÷ 8。
举个例子。原始IP数据报总长度4000字节,IP头部20字节,数据部分3980字节。MTU=1500字节,每个分片最大数据部分 = (1500 - 20) = 1480字节。1480 ÷ 8 = 185,正好是整数。
| 分片编号 | 数据长度(字节) | 片偏移(÷8) | MF标志 |
|---|---|---|---|
| 分片1 | 1480 | 0 | 1 |
| 分片2 | 1480 | 185 | 1 |
| 分片3 | 1020 | 370 | 0 |
分片3的数据长度为什么是1020?因为3980 - 1480 - 1480 = 1020。它不需要对齐到8的倍数,因为它是最后一个。
我曾经踩过的坑:写抓包分析脚本时,直接把片偏移当成字节偏移来用,结果重组出来的数据全是乱码。记住,片偏移 × 8 = 实际字节偏移,这个乘8千万别漏。
3.4 重组过程——收件人自己拼
重组只在目的主机的IP层完成。路由器只负责切,不负责拼。
重组流程:
- 收到第一个分片时,根据Identification、源IP、目的IP、协议号创建一个重组缓冲区。
- 启动一个定时器(通常30秒到2分钟,取决于实现)。
- 后续分片到达后,根据片偏移放入缓冲区对应位置。
- 当收到MF=0的分片,且所有分片都已到齐(通过总长度和片偏移可以算出),开始重组。
- 重组完成后,将完整的IP数据报交给上层协议。
如果定时器超时还有分片没到,整个数据报被丢弃,同时发送ICMP超时差错报文(类型11,代码1)。
注意:分片不携带传输层头部(TCP/UDP头只在第一个分片里)。如果中间分片丢失,TCP无法通过序列号感知,只能靠IP层超时重传整个数据报。所以分片越多,丢包概率越大,性能越差。
3.5 分片与重组的完整流程
下面这张图把整个过程串起来了:
3.6 分片的实际影响与避坑
分片不是免费的。它带来的问题:
- 性能开销:路由器需要额外CPU处理分片,目的主机需要内存和CPU重组。
- 丢包放大:一个分片丢了,整个数据报都得重传。
- 安全风险:分片重叠攻击、Teardrop攻击都是利用重组逻辑漏洞。
我建议:现代网络里,尽量让TCP层做分段(MSS协商),避免IP分片。把DF位置1,让TCP自己控制报文大小。这样既高效又安全。
我曾经遇到一个案例:某客户内网传输大文件,速度奇慢。抓包一看,所有UDP包都被分片了,而且中间某条链路的MTU只有1400,导致大量分片丢失重传。最后把UDP应用改成TCP,配合MSS钳制,问题解决。记住,UDP + 大载荷 = 分片灾难。
3.7 小结
IP分片与重组,核心就三件事:
- MTU是硬边界,超了就得分片。
- 片偏移以8字节为单位,计算时别忘乘8。
- 重组只在目的主机做,超时未完成就丢弃。
嗯,这一节的内容就这些。分片虽然看起来简单,但实际网络里它往往是隐蔽的性能杀手。下次你遇到“网速慢但CPU和带宽都不高”的怪现象,不妨先查查有没有分片在作祟。