Linux网络--IP 分片和组装的具体过程

大家好,我们今天来继续学习Linux的网络部分。上一次我们学习了网络层协议IP,那么今天我们来对IP协议进行一些补充。那么话不多说我们开始今天的学习:

目录

[IP 分片和组装的具体过程](#IP 分片和组装的具体过程)

[1. 分片与组装的过程](#1. 分片与组装的过程)

[1.1 分片](#1.1 分片)

[1.2 组装](#1.2 组装)

[2. 分片与组装过程的示意图](#2. 分片与组装过程的示意图)

[2.1 分片组装场景](#2.1 分片组装场景)


IP****分片和组装的具体过程

我们上次学习了这是IP协议的报文格式,今天我们来学习有关第二行的这三个部分(16位标识,3位标志,13位片偏移),我们上次说了这三部分是为了IP内容进行分片时用的。

16 位标识 (id): 唯一的标识主机发送的报文 . 如果 IP 报文在数据链路层被分片了, 那么每一个片里面的这个 id 都是相同的 .
3 位标志字段 : 第一位保留 ( 保留的意思是现在不用 , 但是还没想好说不定以后要用到). 第二位置为 1 表示禁止分片 , 这时候如果报文长度超过 MTU, IP 模块就会丢弃报文. 第三位表示 " 更多分片 ", 如果分片了的话 , 最后一个分片置为 0, 其他是 1. 类似于一个结束标记.
13 位分片偏移 (framegament offset): 是分片相对于原始 IP 报文开始处的偏移 .其实就是在表示当前分片在原报文中处在哪个位置. 实际偏移的字节数是这个值 除以 8 得到的 . 因此 , 除了最后一个报文之外 ( 之前如果都是 8 的整数倍,最后一片的偏移量也一定是 8 的整数倍 ), 其他报文的长度必须是 8 的整数倍 ( 否则报文就不连续了).
注意:片偏移 (13 位 ) 表示本片数据在它所属的原始数据报数据区中的偏移量(以 8 字节为单位)

1. 分片与组装的过程

1.1 分片
  1. 检查 MTU 限制:
    当一个 IP 数据报的大小超过了网络的 MTU(最大传输单元)限制时,就需要进行分片。MTU 是数据链路层对 IP 层数据包进行封装时所能接受的最大数据长度。
  2. 分割数据报:
    IP 层将原始的 IP 数据报分割成多个较小的片段。对于每个片段,IP 层会设置相应的标识(Identification)、偏移量(Fragment Offset)和标志位(Flags)等字段。标识字段用于标识属于同一个数据报的不同分片,确保所有分片能够被正确地重新组装。
    偏移量字段指示了当前分片相对于原始数据报的起始位置,以 8 字节为单位。
    标志位字段包含了 3 个位,其中 MF(More Fragment)位用于指示是否还有更多的分片,DF(Do Not Fragment)位用于指示数据报是否允许进行分片。
  3. 添加 IP 头部:
    每个分片都会加上自己的 IP 头部,与完整 IP 报文拥有类似的 IP 头结构,但MF 和Fragment Offset 等字段的值会有所不同。
  4. 发送分片:
    分片在传输过程中独立传输,每个分片都有自己的 IP 头部,并且各自独立地选择路由。
1.2 组装
  1. 接收分片:
    当目的主机的 IP 层接收到这些分片后,会根据标识字段将属于同一个数据报的所有分片挑选出来。
  2. 排序与组装:
    利用片偏移字段,IP 层会对属于同一个数据报的分片进行排序。
    当所有的分片都到达并正确排序后,IP 层会将这些分片重新组装成一个完整
    的 IP 数据报。
  3. 传递给上层协议:
    组装好的 IP 数据报会传递给上层的协议进行处理。
    注意:
    IP 分片对传输层是透明的,这意味着传输层无需关心数据是否被分片以及如何重新组装。
    接收方如何得知自己收到的报文分片了?
    接收方通过 IP 头部的标志位(MF)和片偏移(Offset) 组合判断,规则如下:
    若满足以下任一条件,说明是分片报文:
    MF=1(无论片偏移是否为 0):表示当前分片后还有更多分片;
    MF=0 但 片偏移>0:表示当前是最后一个分片(后续无分片,但片偏移非 0 说明是拆分后的一部分)。
    若 MF=0 且 片偏移=0:说明是未分片的完整报文,直接交付上层协议。
    示例
    分片 1:MF=1、片偏移=0 → 是分片(第一个分片);
    分片 2:MF=1、片偏移=1480/8=185 → 是分片(中间分片);
    分片 3:MF=0、片偏移=2960/8=370 → 是分片(最后一个分片);
    完整报文:MF=0、片偏移=0 → 未分片。
    接收方如何得知自己收到的分片收全了?
    接收方需先按 "同一原始报文" 分组,再通过计算验证是否收全所有分片,步骤如下:
    1. 第一步: 分组分片(确定哪些分片属于同一原始报文)
    接收方将具有以下 4 个字段完全相同的分片归为一组(唯一标识一个原始报文):
    源 IP 地址
    目的 IP 地址
    协议号(如 TCP=6、UDP=17,对应上层协议)
    标识(ID)字段
    原因:同一原始报文的所有分片,这 4 个字段必然一致;不同原始报文的标识(ID)由发送方随机生成,重复概率极低。
    2. 第二步: 定位最后一个分片
    在同一组分片的,找到 MF=0 的分片 → 该分片是最后一个分片,其片偏移和数据长度是判断收全的关键。
    3. 第三步: 计算验证是否收全
    核心逻辑:所有分片的有效数据长度之和 = 原始报文的数据总长度,而原始报文的数据总长度可通过最后一个分片计算得出:
    公式推导
    最后一个分片的 "数据起始位置" = 片偏移 × 8(因片偏移单位是 8 字节);
    最后一个分片的 "数据长度" = 该分片的 IP 总长度 - 该分片的 IP 头部长度(IHL×4 字节);
    原始报文的数据总长度 = 最后一个分片的起始位置 + 最后一个分片的有效数据长度。
    验证步骤
    计算每组中每个分片的有效数据长度:
    分片有效数据长度 = 分片的 IP 总长度 - 分片的 IP 头部长度(IHL×4);
    累加所有分片的有效数据长度,得到 "已接收数据总长度";
    计算 "原始报文数据总长度"(用最后一个分片的片偏移和有效数据长度);
    若 "已接收数据总长度" = "原始报文数据总长度" → 分片收全;否则,等待未收到的分片(超时未收到则丢弃所有分片)。
    简化示例
    假设原始报文数据总长度 = 3000 字节,MTU=1500 字节(IP 头部 20 字节,每个分片的数据部分最大 1480 字节):
    分片 1:IP 总长度 = 1500(20+1480),片偏移 = 0 有效数据 = 1480;
    分片 2:IP 总长度 = 1500(20+1480),片偏移 = 1480/8=185 有效数据 = 1480;
    分片 3:IP 总长度 = 3000-1480×2 +20= 60(20+40),片偏移 = 2960/8=370,MF=0 有效数据 = 40;
    累加有效数据:1480+1480+40=3000 与原始数据总长度相等,收全。
    接收方如何组合形成完整的报文?
    分片收全后,接收方按以下步骤重组为原始完整的 IP 报文,流程透明于传输层:
    1. 排序分片
    将同一组的所有分片,按片偏移(Offset)字段值从小到大排序(因分片可能乱序到达,需按原始位置排列)。
    2. 提取并拼接数据载荷
    对每个排序后的分片,剥离其 IP 头部(仅保留数据载荷部分);
    按排序顺序,将所有分片的载荷数据首尾拼接 → 得到原始报文的完整数据载荷。
    3. 构造完整的 IP 报文
    以第一个分片的 IP 头部为基础(第一个分片的头部包含原始报文的关键信息:版本、TTL、协议号、源 / 目的 IP 等);
    修正第一个分片的 IP 头部:
    总长度字段:改为原始报文的总长度(IP 头部长度 + 拼接后的完整数据载荷长度);
    标志位:设为 MF=0、DF=原始值(恢复未分片时的标志位状态);
    片偏移:设为 0;
    校验和:重新计算 IP 头部校验和(因总长度、标志位、片偏移字段修改,原校验和失效)。
    4. 交付上层协议
    将重组后的完整 IP 报文,交给 IP 头部 "协议号" 指定的传输层协议(TCP/UDP),传输层仅需处理完整数据,无需知晓分片过程。

2. 分片与组装过程的示意图

2.1 分片组装场景


好了现在我们学完了IP分片和组装的内容,是不是感觉对网络的认识又深了一步呢?但是在实际使用中,还是尽量不要分片的好,毕竟这会增加丢包的概率。
如果感觉有收获的话还请点赞收藏,那么我们下次再见!

相关推荐
JY.yuyu7 小时前
ACL访问控制列表
运维·服务器·网络
濊繵7 小时前
Linux网络--NAT、代理服务、内网穿透
网络
while(1){yan}7 小时前
HTTP的加密过程
java·开发语言·网络·网络协议·http·青少年编程
重生之我是Java开发战士7 小时前
【计算机网络】数据链路层:从帧传输到高速以太网的完整梳理
网络·网络协议·计算机网络
运维行者_7 小时前
APM 性能监控是什么?从应用监控与网站监控了解基础概念
网络·数据库·云原生·容器·kubernetes·智能路由器·运维开发
yy我不解释7 小时前
关于电脑支不支持5Gwifi、无法找到5Gwifi、5Gwifi没有网络的配置问题
网络·5g·电脑
十月南城7 小时前
统一日志与链路ID的价值——为什么要结构化日志、如何通过关联ID提升排障效率
运维·网络
huangyuchi.7 小时前
【Linux网络】UDP协议详解:透过源码看透“面向数据报”与“缓冲区”的本质
linux·网络·udp·报文·linux网络·传输层协议·报头