IP 数据包的分片与重组是怎么回事?
简化版
每条链路能传输的数据帧有大小上限,叫 MTU(最大传输单元,以太网通常 1500 字节)。当一个 IP 数据包超过 MTU,就必须被分片(Fragmentation)——拆成多个小片分别传输,每片都带上标识和偏移量;到达目的主机后再重组(Reassembly)还原成原始数据包。分片靠 IP 头里的标识、标志(DF/MF)、片偏移三个字段协同完成。
详细版
为什么要分片:数据链路层对帧大小有限制(MTU)。以太网 MTU 是 1500 字节,一个 IP 包如果比这大,链路层塞不下,就得在网络层拆成多个不超过 MTU 的分片。
分片靠 IP 头的三个字段:
- 标识(Identification):同一个原始包的所有分片,标识相同——重组时靠它认出「这些片是一家的」;
- 标志(Flags):
- DF(Don’t Fragment):为 1 表示「不允许分片」。如果包超过 MTU 又不许分片,路由器会丢弃它并回 ICMP 差错;
- MF(More Fragments):为 1 表示「后面还有分片」,最后一片为 0;
- 片偏移(Fragment Offset):本片数据在原始包里的位置(以 8 字节为单位)——重组时靠它把各片按正确顺序拼回去。
重组在哪做:分片可能沿途被多个路由器进一步拆分,但重组只在最终目的主机进行(中间路由器不重组),由目的主机收齐所有分片后按标识+偏移拼回原包。
完整版教学
一、MTU:链路的「限高杆」
理解分片,先理解 MTU(Maximum Transmission Unit)。每种链路层技术对一个帧能携带的数据量有上限:
- 以太网 MTU = 1500 字节(最常见);
- 其他链路(如某些 VPN、隧道、PPPoE)MTU 可能更小。
MTU 就像道路的「限高杆」——超高的车(超大的 IP 包)过不去,必须拆分。IP 层负责把过大的数据包拆成一个个不超过 MTU 的分片,才能塞进链路层的帧里传输。
二、三个字段如何协同完成分片与重组
分片和重组是一套精密的配合,全靠 IP 头的标识、标志、片偏移:
分片时:一个大包被拆成几片,每片:
- 标识都设成相同的值(表明同源);
- 除最后一片外,MF 都置 1(表示后面还有);最后一片 MF=0;
- 片偏移记录本片数据在原包中的起始位置。
重组时(在目的主机):
- 用标识把属于同一个原始包的分片归拢到一起;
- 用片偏移确定每片的正确位置、按序拼接;
- 看到 MF=0 的那一片,知道「最后一片到了」,且偏移最大——据此判断是否收齐所有分片,收齐就重组成原包交给上层。
原始包(3000B 数据)分成 3 片(每片数据 ≤ MTU):
片1: 标识=X, MF=1, 偏移=0 数据[0~1479]
片2: 标识=X, MF=1, 偏移=185 数据[1480~2959] (偏移以8字节为单位: 1480/8=185)
片3: 标识=X, MF=0, 偏移=370 数据[2960~...] (最后一片)
三、为什么重组只在目的主机做
分片可能在传输途中被不同的路由器多次拆分(如果后续链路 MTU 更小)。如果每个中间路由器都尝试重组,代价太大、也不现实(分片可能走不同路径、到达顺序不定)。所以设计上:
- 中间路由器只管转发分片、必要时进一步拆分,不重组;
- 重组统一在最终目的主机进行——它收齐所有分片后一次性拼回。
这简化了路由器的工作,让它专注转发。
四、分片的代价与「尽量避免分片」
分片虽然让大包能通过小 MTU 的链路,但有明显代价:
- 效率降低:每个分片都要加一份 IP 头,开销变大;
- 丢一片全完蛋:只要任何一个分片丢失,整个原始包就无法重组,得整个重传(IP 不重传,得靠上层 TCP 重发整段)——放大了丢包的影响;
- 重组消耗资源:目的主机要缓存分片等待重组,也是一种负担和攻击面(分片攻击)。
所以现代网络倾向于尽量避免 IP 分片,主要靠:
- TCP 的 MSS 协商:TCP 在建连时协商 MSS(最大报文段长度),让每个 TCP 段的大小控制在「不会触发 IP 分片」的范围内(MSS 通常 = MTU − IP头 − TCP头 = 1500 − 20 − 20 = 1460),从源头就不产生超 MTU 的包;
- Path MTU Discovery(路径 MTU 发现):给包设 DF=1(不分片),如果途中某链路 MTU 太小会回 ICMP 报错告知 MTU 大小,发送方据此减小包大小——找到整条路径的最小 MTU,全程不分片。
五、常见误区
- ❌ 以为分片在中间路由器重组——重组只在最终目的主机做,中间路由器只转发/继续拆分。
- ❌ 以为丢一个分片只重传那一片——IP 不重传,任何一片丢了整个原包都要靠上层(TCP)重传整段。
- ❌ 把 MTU 和 MSS 搞混——MTU 是链路层帧的数据上限(含 IP/TCP 头),MSS 是 TCP 段的数据上限(不含头),MSS ≈ MTU − 40。
- ❌ 以为分片越多越好——分片有开销且放大丢包影响,现代网络靠 MSS 协商和 PMTUD 尽量避免分片。
六、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| MTU | 链路层单帧最大承载大小 |
| 分片 | IP 包超过路径 MTU 时拆成多个片 |
| 风险 | 丢一个片整个原始包都无法重组 |
IP packet 4000 bytes
Ethernet MTU 1500
-> fragment #1
-> fragment #2
-> fragment #3
one fragment lost -> whole packet retransmitted by upper layer
分片发生在 IP 层,但重传通常靠 TCP 等上层;一个片丢了,代价会被放大。
- 误区:TCP MSS 和 IP MTU 是一回事。 MTU 是链路层最大包,MSS 是 TCP 负载最大段,MSS 通常约等于 MTU 减 IP/TCP 头。
- 误区:分片越多吞吐越高。 分片增加头部开销和丢片风险,通常应尽量避免。
- 误区:所有 IPv6 路由器都能像 IPv4 一样中途分片。 IPv6 中路由器不分片,源主机应基于路径 MTU 发送合适大小。
- 追问:DF 标志有什么用? IPv4 设置 DF 后禁止中途分片,包太大时返回需要分片的 ICMP。
- 追问:路径 MTU 发现解决什么? 探测整条路径可承载的最大包,避免中途分片。
- 追问:为什么分片影响性能? 每片都有头部和重组成本,任一片丢失会导致整个原始数据报不可用。
七、加强记忆
链路有 MTU 上限(以太网 1500 字节),超过就要 IP 分片——靠 IP 头的标识(同源)、标志 DF(禁止分片)/MF(后面还有片)、片偏移(本片位置)协同拆分,重组只在最终目的主机做。分片有代价(开销大、丢一片要整包重传),所以现代网络靠 TCP 的 MSS 协商(≈MTU−40)和路径 MTU 发现(DF=1 + ICMP)从源头尽量避免分片。