
1. 为什么需要IP数据报分片第一次接触IP分片这个概念时我正调试一个视频会议系统。当时发现某些大尺寸视频包总是传输失败而小文件却能正常传输。经过抓包分析才发现原来问题出在IP分片上。这让我意识到理解IP分片机制对网络工程师来说有多重要。**MTU最大传输单元**就像快递公司的货车载重限制。以太网的MTU默认是1500字节相当于一辆标准货车最多能装1500公斤货物。当我们要发送的IP数据报超过这个限制时就必须像拆分大件家具一样把数据报分成多个小包裹运输。这里有个容易混淆的概念MTU包含IP首部。一个1500字节的MTU实际能承载的数据部分是1480字节减去20字节的IP首部。我在实际项目中就犯过这个错误计算时漏掉了首部空间导致分片计算全部出错。不同网络环境的MTU值可能不同以太网1500字节PPPoE拨号1492字节某些VPN隧道更小的值当数据包从MTU较大的网络进入MTU较小的网络时路由器就会执行分片操作。这就像国际物流中的转运——货物从海运大集装箱转到空运小货舱时必须重新分装。2. IP分片的三大核心要素2.1 标识字段包裹的快递单号每个IP数据报都有个16位的唯一标识符就像快递单号。我曾在实验室做过测试连续发送10个ICMP请求包它们的ID依次递增。当这些包被分片时所有分片都携带相同的ID值。这个设计很巧妙——接收端靠这个ID就能识别哪些分片属于同一个原始数据报。在实际抓包时我常用这个特性来追踪特定数据流的分片情况。2.2 标志字段包裹的注意事项标志字段只有3位但信息量很大DF位Dont Fragment设为1时表示易碎品不可拆分。某些应用如NFS会设置这个标志如果路径上遇到MTU较小的链路路由器会丢弃包并返回ICMP错误。我在配置路由器时遇到过这种情况当DF包被丢弃时会触发需要分片的ICMP错误这其实是PMTUD路径MTU发现机制的基础。MF位More Fragments相当于还有后续包裹的标记。最后一个分片会把这个位设为0其他分片都设为1。有次网络故障就是因为最后一个分片的MF位错误地设为1导致接收端一直等待不存在的分片。2.3 片偏移拼图的定位指南片偏移量以8字节为单位表示当前分片数据在原始数据报中的起始位置。举个例子第一个分片偏移量为0第二个分片如果携带1400字节数据它的偏移量就是1751400÷8这里有个关键细节除了最后一个分片其他分片的数据长度必须是8的整数倍。这是因为片偏移字段只有13位最大表示81912¹³-1乘以8就是65528字节刚好略小于IP数据报的最大长度65535字节。3. 分片过程实战解析3.1 分片场景模拟假设我们要发送一个3820字节的IP数据报20字节首部3800字节数据通过MTU1500的以太网。可用载荷空间是1500-201480字节。但实际分片时每个分片都要带新的IP首部20字节所以有效载荷是1480字节。由于3800÷1480≈2.57需要3个分片前两个分片各带1480字节数据最后一个带剩余的840字节3800-1480×2但这样计算有问题因为片偏移要求分片数据长度除最后一片必须是8的倍数。1480÷8185刚好是整数所以这个案例可以这样分。如果数据量不是8的整数倍就需要调整。3.2 分片后的首部变化每个分片都有自己的IP首部其中关键字段变化如下第一分片总长度150020首部1480数据标志DF0MF1还有后续分片片偏移0第二分片总长度1500标志DF0MF1片偏移1851480÷8第三分片总长度86020840标志DF0MF0片偏移3701480×2÷8通过Wireshark抓包可以看到分片后的IP包ID完全相同只有上述字段有差异。这就像把一本书分成三卷邮寄每卷的ISBN号相同但封面注明第一卷第二卷。4. 重组过程中的技术细节4.1 接收端如何重组接收端重组分片就像玩拼图根据ID识别属于同一数据报的分片按照片偏移排序检查MF标志确认是否收齐所有分片这里有个超时机制如果在一定时间内通常是30秒或60秒没有收到全部分片就会丢弃已收到的分片。我在排查网络问题时就曾发现因为最后一个分片丢失导致整个传输失败的情况。4.2 分片带来的性能问题分片虽然解决了大包传输问题但也带来明显开销传输效率下降每个分片都要携带IP首部造成带宽浪费。上面的例子中3820字节原始数据变成了150015008603860字节多出40字节开销。重组消耗资源接收端需要缓存和管理分片对路由器性能是考验。有次网络攻击就是利用发送大量不完整分片耗尽设备内存。错误恢复困难TCP协议中任何一个分片丢失都会导致整个TCP段重传。这就是为什么TCP会主动避免分片通过MSS协商。5. 实际应用中的注意事项5.1 避免分片的优化方案在生产环境中我们通常会调整应用层数据大小比如HTTP/2就建议帧不超过16KB启用PMTUD让系统自动发现路径MTU设置合理的MSSTCP连接建立时会协商MSS最大分段大小通常设为MTU-40IP首部20TCP首部20我在配置Linux服务器时常用这个命令设置MTUsudo ifconfig eth0 mtu 14925.2 分片与网络安全分片可能被用于规避安全检测Tiny Fragment攻击把TCP头信息拆分到第二个分片绕过防火墙的端口检查分片重叠攻击发送偏移量异常的分片导致系统崩溃防御措施包括配置防火墙拒绝极小的分片比如小于60字节启用分片重组检查对分片流量进行限速6. 抓包分析实战用tcpdump抓取分片包的命令sudo tcpdump -i eth0 ip[6] 0x20 ! 0 or ip[6] 0x1f ! 0 -vv这个过滤条件会捕获所有分片包MF1或片偏移0。分析分片时重点关注Identification字段是否相同MF标志和片偏移的连续性各分片到达的时间顺序有次排查视频卡顿问题就是通过抓包发现分片乱序到达导致接收端重组超时。后来通过调整QoS策略解决了这个问题。7. 不同协议对分片的影响7.1 TCP与分片TCP协议通过MSS协商尽量避免分片。建立连接时的三次握手中双方会通告自己的MSS值通常是MTU-40。现代操作系统还支持RFC4821定义的PMTUD路径MTU发现机制。7.2 UDP与分片UDP应用需要特别注意DNS通常响应小于512字节但EDNS0允许更大响应NTP默认使用短报文视频流需要合理设置分片大小我曾优化过一个VoIP系统把语音包大小控制在120字节以内完全避免了分片显著提升了通话质量。8. IPv6的分片变化IPv6的分片机制有重大变化只有源节点可以分片路由器不再分片通过分片扩展头实现默认使用PMTUD配置IPv6网络时需要确保所有链路MTU≥1280字节IPv6要求的最小MTU。这个改变让网络中间设备更简单但也要求应用层更注意数据大小。