文章目录
前言

- 16位标识 (id): 唯⼀的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每⼀片里面的这个id都是相同的.
- 3位标志字段 : 第1位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第2位置为1表示禁止分片 , 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第3位表示"是否还有更多分片" , 如果分片了的话, 最后⼀个分片置为0, 其他是1. 类似于⼀个结束标记.
- 13位分片偏移 (framegament offset): 是分片相对于原始IP报文开始处的偏移 . 其实就是在表示当前分片在原报文中处在哪个位置. 实际偏移的字节数是这个值 乘 8 得到的 . 因此, 除了最后⼀个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了).
IP分片与组装是IP协议中用于处理数据报大小超过网络最大传输单元(MTU)时的一种机制:
一、IP分片
为什么需要IP分片
不同的网络链路和网络类型有不同的最大传输单元(MTU) 。MTU是指数据链路层对IP层数据包进行封装时所能接受的最大数据长度,以字节为单位 。当IP数据报的大小超过出接口的MTU时,就需要将数据报分割成多个较小的片段 ,每个片段称为一个分片 ,然后分别传输这些分片。在目的地,这些分片被重新组装成原始数据报。
分片过程
分片发生在IP层 。当路由器或主机需要发送一个超过MTU的IP数据报 时,它会将数据报分成若干分片 。每个分片都是一个独立的IP数据包,具有自己的IP头 。分片后的数据包在到达目的地之前可能会经过不同的路径,因此分片可能不按顺序到达。
- 检查MTU限制:
当⼀个IP数据报的大小超过了网络的MTU(最大传输单元)限制时,就需要进行分片。 - 分割数据报:
a. IP层将原始的IP数据报分割成多个较小的片段。
b. 对于每个片段,IP层会设置相应的16位标识(Identification)、13位偏移量(Fragment Offset)和标志位(Flags)等字段。
c. 16位标识字段用于标识属于同⼀个数据报的不同分片,确保所有分片能够被正确地重新组装。
d. 13位偏移量字段指示了当前分片相对于原始数据报的起始位置,以8字节为单位。
e. 标志位字段包含了3个位,其中MF(More Fragment)位用于指示是否还有更多的分片,DF
(Do Not Fragment)位用于指示数据报是否允许进行分片。 - 添加IP头部:
每个分片都会加上自己的IP头部,与完整IP报文拥有类似的IP头结构,但MF和Fragment Offset
等字段的值会有所不同。 - 发送分片:
分片在传输过程中独立传输,每个分片都有自己的IP头部,并且各自独立地选择路由。
二、IP组装
组装发生在目的地的IP层。当目的主机收到一个分片时,它开始组装过程。所有具有相同标识、源IP地址和目的IP地址的分片将被重组成原始数据报。
组装过程
- 接收并初始化
当收到第一个分片时,主机分配一个重组缓冲区,用于存储该数据报的所有分片。 - 三元组标识
根据分片的源IP、目的IP和标识符来区分不同的数据报分片。 - 数据归位
将每个分片的数据放到重组缓冲区中正确的位置(根据片偏移计算)。 - 完整校验
当收到MF位为0的分片(即最后一个分片)时,记录该数据报的总长度。当所有分片都到达(从偏移0到最后一个分片)且没有重叠时,组装完成。 - 超时清理
如果在一定时间内(重组超时时间,通常为30秒或60秒)没有收到所有分片,则丢弃所有已收到的分片,并可能向源端发送ICMP超时错误。
三、样例
有一个3000字节的IP数据报(包括IP头部20字节,所以数据部分为2980字节),要通过一个出接口MTU为1500字节的链路。我们需要分片与组装:
- 每个分片都需要一个IP头部(20字节),所以每个分片的数据部分最大为MTU-20=1480字节。
- 我们需要将2980字节的数据分成多个分片,每个分片的数据部分必须是8字节的整数倍,除了最后一个分片可以不是。
每个分片如下:
| 标识符 | 分片序号 | 分片偏移量(8字节/位) | 数据范围 | 数据长度 | MF位 | 分片总长度(IP头+数据) |
|---|---|---|---|---|---|---|
| 0xABCD | 分片1 | 0 | 0~1479 | 1480字节 | 1 | 1500字节 |
| 0xABCD | 分片2 | 185 | 1480~2959 | 1480字节 | 1 | 1500字节 |
| 0xABCD | 分片3 | 370 | 2960~2979 | 20字节 | 0 | 40字节 |
- 接收主机进行组装
组装原则:
是否同一分组 : 同属于0xABCD
偏移连续性 :对同一个数据报的分片进行排序,0→185→370连续
MF标志序列 :1→1→0正确
数据覆盖 :0-2979完整覆盖
总长度一致:2980+20=3000字节
最后将还原后的原始数据交付给上层
1.接收方如何得知收到的报文分片了?
当报文的 MF位为1 或者 片偏移量>0 满足一个,即可认为报文分片
2.接收方如何得知分片收全了?
必须收到"片偏移=0"的第一个分片,并且必须收到"MF标志=0"的最后一个分片,同时确保从0到最后一个分片之间的所有数据片段(通过"片偏移"和"数据长度"计算)已连续到达,无任何缺失间隙。
3.接收方如何组合形成完整报文?
接收方按"片偏移"值由小到大排序所有分片,然后依次将每个分片的数据部分复制到重组缓冲区中由"片偏移"指定的精确位置,最终拼接还原出原始的完整报文数据
注意:
- 分片和重组是一个耗时的过程,会增加延迟和处理开销。因此,现代网络尽量避免分片,通常由发送主机执行路径MTU发现(Path MTU Discovery)来确定路径上的最小MTU,然后发送不超过该MTU的数据报。
- IP分片对传输层是透明的。TCP、UDP 等传输层协议看不到分片过程,仅接收组装后的完整数据;若某一分片丢失,IP 层不重传,需依赖 TCP 的重传机制(UDP 无重传,会导致数据丢失)。
- 数据报分片越多,丢失的概率越大,即相对来说效率越低。只要有一个分片丢失,整个原始数据报就无法组装,需等待上层协议重传(TCP 会重传完整原始报文,UDP 则直接丢失数据)。