目录
- [1.网络层 VS 传输层](#1.网络层 VS 传输层)
-
- [1.1 网络层(Network Layer):负责 "找路" 和 "送达主机"](#1.1 网络层(Network Layer):负责 “找路” 和 “送达主机”)
- [1.2 传输层(Transport Layer):负责 "分拣" 和 "数据完整"](#1.2 传输层(Transport Layer):负责 “分拣” 和 “数据完整”)
- [1.3 二者的协作关系](#1.3 二者的协作关系)
- [1.4 举例类比:寄快递](#1.4 举例类比:寄快递)
- [2. IP协议的核心作用和构成](#2. IP协议的核心作用和构成)
-
- [2.1 核心逻辑:寻址与定位](#2.1 核心逻辑:寻址与定位)
- [2.2 IP 地址的构成:两级结构](#2.2 IP 地址的构成:两级结构)
- [2.3 网络设备的基本概念](#2.3 网络设备的基本概念)
- [2.4 IP 协议的工作机制](#2.4 IP 协议的工作机制)
- [2.5 IP 协议头的格式](#2.5 IP 协议头的格式)
- [3. 网段划分(重点)](#3. 网段划分(重点))
- [4. 特殊的IP地址](#4. 特殊的IP地址)
- [5. IP地址的数量限制](#5. IP地址的数量限制)
- [6. 私有IP地址和公网IP地址](#6. 私有IP地址和公网IP地址)
- [7. 尝试理解公网](#7. 尝试理解公网)
- [8. 路由](#8. 路由)
- [9. 网络通信中的 IP 分片问题全解析(AI生成)](#9. 网络通信中的 IP 分片问题全解析(AI生成))
-
- [9.1 分片在各层的核心操作](#9.1 分片在各层的核心操作)
-
- [9.1.1 数据链路层:分片的 "触发源头",仅做被动限制](#9.1.1 数据链路层:分片的 “触发源头”,仅做被动限制)
- [9.1.2 IP 网络层:分片的 "唯一执行者",也是组装的 "唯一完成者"](#9.1.2 IP 网络层:分片的 “唯一执行者”,也是组装的 “唯一完成者”)
- [9.1.3 传输层:主动 "规避分片",不参与分片 / 组装](#9.1.3 传输层:主动 “规避分片”,不参与分片 / 组装)
- [9.1.4 应用层:分片的 "终极规避",控制报文原始大小](#9.1.4 应用层:分片的 “终极规避”,控制报文原始大小)
- [9.2 分片的核心基础:最大尺寸、MTU 与报文大小的关系](#9.2 分片的核心基础:最大尺寸、MTU 与报文大小的关系)
-
- [9.2.1 分片的最大尺寸:单分片长度≤**出接口链路 MTU**,且非最后分片为 8 字节整数倍](#9.2.1 分片的最大尺寸:单分片长度≤出接口链路 MTU,且非最后分片为 8 字节整数倍)
- [9.2.2 报文大小和 MTU 的核心关系](#9.2.2 报文大小和 MTU 的核心关系)
- [9.3 为什么要使用分片?------ 解决跨链路 MTU 不兼容问题](#9.3 为什么要使用分片?—— 解决跨链路 MTU 不兼容问题)
- [9.4 分片和组装不是主流而是被迫为之的原因](#9.4 分片和组装不是主流而是被迫为之的原因)
- [9.5 如何减少分片?减少分片的本质在哪个层级?](#9.5 如何减少分片?减少分片的本质在哪个层级?)
- [9.6 传输层应该交给 IP 的报文多大时,IP 不会分片?](#9.6 传输层应该交给 IP 的报文多大时,IP 不会分片?)
- [9.7 基于 IP 头标识 / 标志 / 片偏移的分片与组装实战](#9.7 基于 IP 头标识 / 标志 / 片偏移的分片与组装实战)
- [9.8 补充:IPv6 对分片的改进(无中间路由器分片,仅源主机分片)](#9.8 补充:IPv6 对分片的改进(无中间路由器分片,仅源主机分片))
- [9.9 总结](#9.9 总结)
1.网络层 VS 传输层
前面已经对应用层(自定义应用层协议)和传输层(TCP、UDP)进行了理解,接下来将对网络层进行学习!

TCP/IP 协议的核心功能 (网络的核心问题和功能):把数据 100% 可靠的从 A 主机跨网络送到 B 主机!
为了实现这个看似简单的目标,TCP/IP 协议栈采用了 "分层解耦" 的思想。如果把网络通信比作快递运输,那么 网络层(IP)和传输层(TCP/UDP)就是完成这次任务的两个关键角色。
1.1 网络层(Network Layer):负责 "找路" 和 "送达主机"
核心协议:IP (Internet Protocol)
口号: "尽力而为 (Best Effort)"
- 它的任务: 网络层的核心职责是路由选择 和寻址。它负责在复杂的互联网拓扑中,找到一条从 A 主机到 B 主机的路径,并将数据包(Datagram)从一个路由器转发到下一个路由器,直到到达 B 主机所在的局域网。
- 它的局限性: IP 协议是不可靠 的。它不保证数据包的顺序,不保证数据包不丢失,也不保证数据包不重复。
- 为什么? 因为网络环境是动态变化的,路由器可能拥塞丢包,链路可能中断。如果 IP 层要负责所有的可靠性,网络会变得极其笨重且低效。
- 结论: 网络层解决了 "从 A 主机到 B 主机" 的问题,但它只保证 "尽力送达",不保证 "一定送达"。
1.2 传输层(Transport Layer):负责 "分拣" 和 "数据完整"
核心协议:TCP (Transmission Control Protocol) / UDP
口号: "端到端的可靠性"
- 它的任务: 当网络层把数据包送到 B 主机后,传输层接手。它负责将数据准确无误地交给 B 主机上的特定应用程序(进程)。
- TCP 的角色(可靠性的来源): 为了弥补 IP 层 "不可靠" 的缺陷,TCP 在端对端(End-to-End)之间建立了逻辑连接。它通过序列号、确认应答 (ACK)、重传机制、流量控制、拥塞控制 等手段,在不可靠的 IP 网络之上,构建了一条可靠的、有序的、无差错的数据流通道。
- UDP 的角色: 如果你不需要 100% 可靠(比如视频通话、直播),UDP 则提供了一种 "尽力而为" 的传输,它只负责把数据扔给应用层,不做任何校验。
- 结论: 传输层解决了 **"从 A 进程到 B 进程"的问题,并由 TCP 确保了数据的100% 可靠性 **。
1.3 二者的协作关系
为了实现 "把数据 100% 可靠地从 A 送到 B" 这一终极目标,两层协议进行了完美的分工:
- 网络层(IP) 负责跨越千山万水 ,解决了连通性问题(把信送到了对方小区的传达室)。
- 传输层(TCP) 负责保证质量 ,解决了可靠性问题(确保传达室把信完好无损、按顺序交到了收信人手里,少一页就重送)。
没有网络层,数据出不去;没有传输层(TCP),数据不可信。
1.4 举例类比:寄快递
为了彻底理解,我们可以用 "寄快递" 来类比:
- 网络层(IP) = 物流公司与卡车司机
- 司机负责把包裹从北京运往上海(跨网络传输)。
- 路上可能遇到堵车(延迟)、车祸(丢包)、或者包裹被雨水淋湿(比特翻转)。
- 司机的原则是 "尽力开",但他不负责包裹里的东西坏没坏,也不负责包裹是不是按发货顺序到的。
- 传输层(TCP) = 寄件人与收件人的电话沟通
- 当卡车把一堆包裹扔到收件人门口时,收件人(TCP)开始清点。
- "哎?第 3 个包裹碎了,重发!"(重传机制)
- "哎?第 2 个包裹还没到,我先等等,别乱了顺序。"(排序与缓存)
- "你发货太快了,我门口堆满了,慢点发!"(流量控制)
总结:
正是因为有了网络层的 "尽力传输"加上传输层的"端到端修复",我们才能在浏览器里刷视频、在微信上发消息,享受看似完美的网络体验。
2. IP协议的核心作用和构成
IP 协议(Internet Protocol)的定义:
提供一种无连接的、尽力而为的能力,把数据从 A 主机 ,跨网络 ,送到 B 主机。

2.1 核心逻辑:寻址与定位
为了实现 "跨网络送达",必须有一种机制来标识通信两端的唯一性。
- IP 地址(IP Address): 网络中每台主机的唯一身份证。
- 核心区别:
- IP 协议 解决的是 "主机到主机(Host to Host)" 的问题(把信送到对方家)。
- TCP/UDP 协议 解决的是 "进程到进程(Process to Process)" 的问题(把信交给对方家里的具体某个人),这依靠的是端口号(Port)。
2.2 IP 地址的构成:两级结构
IP 地址不仅仅是一个数字,它本质上是一种逻辑划分:
IP地址 = 网络号(NetworkID) + 主机号(HostID)
- 网络号(目标网络): 代表主机所在的 "区域" 或 "小区"。路由器依靠网络号来决定大方向的路由。
- 主机号(主机): 代表该区域内的 "具体设备"。
- 子网掩码(Subnet Mask): 这是一个关键点,单纯看 IP 地址无法区分哪部分是网络号,哪部分是主机号,必须配合子网掩码(如 255.255.255.0)才能解析出网络号。
2.3 网络设备的基本概念
在 IP 网络中,我们需要区分以下三种角色:
- 主机 (Host):
- 定义: 配有 IP 地址,主要用于运行应用程序、收发数据的终端设备(如 PC、手机、服务器)。
- 特点: 通常不负责转发其他设备的数据包。
- 路由器 (Router):
- 定义: 连接多个网络的枢纽设备。它拥有多个IP 地址(每个接口一个)。
- 核心功能: 路由控制(Routing)。它根据路由表,决定接收到的数据包应该转发到哪个下一跳接口。
- 节点 (Node):
- 定义: 主机 和路由器的统称。
- 含义: 任何需要分配 IP 地址并参与 IP 数据包处理的设备,都可以被称为节点。
2.4 IP 协议的工作机制
仅仅有地址是不够的,IP 协议还通过以下机制实现传输:
-
分片与重组 (Fragmentation & Reassembly):
不同的网络链路(如以太网、WiFi)对数据包大小的限制(MTU)不同。IP 协议负责在发送端将大包 "切" 成小包(分片),在接收端将小包 "拼" 回大包(重组)。
-
路由转发 (Routing):
数据包从源主机发出,经过多个路由器的接力传递(Hop-by-Hop),最终到达目标网络。
-
TTL (Time To Live):
为了防止数据包在网络中无限循环(死循环),每个 IP 包都有一个生存时间,每经过一个路由器减 1,减到 0 则丢弃。
2.5 IP 协议头的格式

4 位版本号 (Version): 指定 IP 协议的版本,IPv4 固定为 4,用于让接收端解析后续的首部格式。
4 位首部长度 (IHL-Internet Header Length): 表示 IP 首部占多少个 32bit 字(即 4 字节的倍数),最小值为 5(20 字节),最大值为 15(60 字节)。
8 位服务类型 (TOS): 用于指示路由器如何处理该数据包,包含 3 位优先权(已弃用)和 4 位标志位(最小延时、最大吞吐量、最高可靠性、最小成本)。
16 位总长度 (Total Length): 指明整个 IP 数据报(首部 + 数据)的总字节数,最大值为 65535 字节,用于接收端判断数据报边界。
16 位标识 (Identification): 唯一标识主机发送的每一份数据报,当报文被分片时,所有分片的该字段值保持一致,用于接收端重组。
3 位标志 (Flags): 包含保留位、DF 位(1 表示禁止分片,超 MTU 则丢弃)和 MF 位(1 表示后面还有分片,0 表示是最后一片)。
13 位片偏移 (Fragment Offset): 表示当前分片在原始报文中的相对位置,单位是 8 字节,用于接收端按序重组数据。
8 位生存时间 (TTL): 限制数据包在网络中的最大跳数,每经过一个路由器减 1,减至 0 则丢弃,用于防止路由环路。
8 位协议 (Protocol): 指示 IP 数据报的数据部分应交给哪个上层协议处理,如 TCP (6)、UDP (17) 或 ICMP (1)。
16 位首部校验和 (Header Checksum): 仅对 IP 首部进行 CRC 校验,用于检测首部在传输过程中是否出现损坏,每经过路由器需重新计算。
32 位源地址 / 目的地址: 分别标识发送数据报的源主机 IP 地址和接收数据报的目的主机 IP 地址。
选项字段 (Options): 用于网络测试或安全等特殊功能,长度可变(0~40 字节),需通过填充字段保证首部长度为 32bit 的整数倍。
3. 网段划分(重点)
IP 地址采用层级结构设计,由网络号 和主机号两部分组成:
- 网络号 (Network ID): 用于标识主机所在的网段,确保相互连接的不同网段拥有独一无二的标识。
- 主机号 (Host ID): 用于标识同一网段内的特定设备,同一网段内的所有主机共享相同的网络号,但必须拥有唯一的主机号。
- 子网 (Subnet) 的概念: 所谓子网,本质上就是将拥有相同网络号的一组主机逻辑地或物理地聚合在一起。
- 新增主机规则: 当在子网中新增一台主机时,该主机必须配置与子网一致的网络号,同时分配一个未被占用的主机号,以确保通信正常。
通过这种层级划分,有效地保证了互联网中每台主机 IP 地址的全局唯一性。
然而,在大型网络环境中,手动静态配置每台主机的 IP 地址是低效且易出错的:
- DHCP 技术 (动态主机配置协议): 为了解决手动管理的不便,引入了 DHCP 技术,它能自动为主机分配 IP 地址及子网掩码、网关等相关参数。
- DHCP 服务器: 家用或企业级路由器通常默认开启 DHCP 服务功能,因此路由器在局域网中也充当了 DHCP 服务器的角色,负责向接入的设备自动下发 IP 配置。

过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类, 如下图所示(该图出 自[TCPIP])。

A类 0.0.0.0到127.255.255.255
B类 128.0.0.0到191.255.255.255
C类 192.0.0.0到223.255.255.255
D类 224.0.0.0到239.255.255.255
E类 240.0.0.0到247.255.255.255
随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址, 导致B类地址很快就分配完了, 而A类却浪费了大量地址;
例如, 申请了一个B类地址, 理论上一个子网内能允许6万5千多个主机. A类地址的子网内的主机数更多.
然而实际网络架设中, 不会存在一个子网内有这么多的情况. 因此大量的IP地址都被浪费掉了.
针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing)(无类别域间路由):
引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
子网掩码也是一个32位的正整数. 通常用一串 "0" 来结尾;
将IP地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号;
网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;

可见,IP地址与子网掩码做与运算可以得到网络号,主机号从全0到全1就是子网的地址范围;
IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68,子网掩码的高24位是1,也就是255.255.255.0。
4. 特殊的IP地址
IP 地址空间中预留了一些特殊的地址段,用于特定的网络功能:
- 网络地址 (Network Address): 将 IP 地址的主机号部分全部置为 0。它代表 "整个网段" 本身,用于路由表标识,不能分配给具体的主机。
- 广播地址 (Broadcast Address): 将 IP 地址的主机号部分全部置为 1 。它用于向同一个局域网内的所有主机发送数据包(受限广播)。
- 环回地址 (Loopback Address): 127.0.0.0/8 网段(如 127.0.0.1)。用于本机进程间通信或测试网络协议栈,数据不会离开本机网卡。
- 私有地址 (Private Address): 在互联网上不被路由的地址,专门用于局域网内部使用。
- A 类: 10.0.0.0 ~ 10.255.255.255
- B 类: 172.16.0.0 ~ 172.31.255.255
- C 类: 192.168.0.0 ~ 192.168.255.255
- 0.0.0.0:
- 源地址时: 表示 "本主机"(通常在主机启动且尚未分配 IP 时使用)。
- 目的地址时: 表示 "所有网络"(通常用于默认路由)。
- 自动专用 IP (APIPA): 169.254.0.0/16。当主机无法联系到 DHCP 服务器时,自动配置的临时地址。

5. IP地址的数量限制
我们知道,IPv4 地址是一个 4 字节(32 位)的正整数,总共有 232 个(约 43 亿个)。
1. 为什么 43 亿还不够用?
虽然 43 亿看起来很多,但实际上可用数量远低于此:
- 特殊地址占用: 网络号、广播地址、私有地址等不能作为公网 IP 使用。
- 分配单位: IP 地址是分配给 ** 网络接口(网卡)** 的,而不是主机。一台服务器可能有多个网卡,IoT 设备的爆发式增长更是加剧了消耗。
- 早期浪费: 早期的分类编址(Class A/B/C)导致了大量的地址浪费。
2. 缓解措施:CIDR
CIDR(无类别域间路由) 技术通过引入 "子网掩码" 和变长掩码,打破了传统的分类界限,极大地提高了 IP 地址的利用率,缓解了浪费现象。
- 注意:CIDR 只是提高了 "人均利用率",并没有增加 IP 地址的 "绝对总量"。
3. 根本解决方案
为了解决 IPv4 地址枯竭的根本问题,目前主要采用以下三种手段:
- 动态分配 (Dynamic Allocation):
- 利用 DHCP 技术,只在设备接入网络时才分配 IP。
- 特点:同一个设备每次接入时,获得的 IP 可能不同(租约机制)。这提高了局域网内部的地址利用率。
- NAT 技术 (网络地址转换):
- 这是目前最核心的救星。通过 NAT,整个局域网内的所有设备只需共享一个或少量几个公网 IP 即可访问互联网。
- 原理:在路由器上进行私有地址与公网地址的转换(后面会重点介绍)。
- IPv6 (终极解决方案):
- 不兼容: IPv6 并非 IPv4 的简单升级,而是一个独立的、不兼容的新一代协议。
- 容量: IPv6 采用 128 位地址空间(2128),地址数量极其庞大(号称能给地球上每一粒沙子分配一个 IP)。
- 现状: 目前全球正在积极部署 IPv6,虽然尚未完全取代 IPv4,但已进入大规模商用阶段,与 IPv4 长期共存。
6. 私有IP地址和公网IP地址
如果一个组织内部组建局域网,IP 地址只用于局域网内的通信,而不直接连到 Internet 上,理论上使用任意的 IP 地址都可以。但是为了规范,RFC 1918 规定了专门用于组建局域网的私有 IP 地址段,这些地址在互联网上是不会被路由的:
- 10.0.0.0 ~ 10.255.255.255 :
- 前 8 位是网络号(/8)。
- 共 16,777,216 个地址。
- 172.16.0.0 ~ 172.31.255.255 :
- 前 12 位是网络号(/12)。
- 共 10,485,760 个地址。
- 192.168.0.0 ~ 192.168.255.255 :
- 前 16 位是网络号(/16)。
- 共 65,536 个地址。
包含在这个范围中的,都称为私有 IP (或内网 IP);其余的则称为全局 IP(或公网 IP)。

-
路由器的双 IP 角色:
一个家用路由器通常配置两个 IP 地址:一个是 WAN 口 IP(连接上级网络),一个是 LAN 口 IP(作为内网网关)。
-
子网独立性:
路由器 LAN 口连接的主机,都从属于当前这个路由器的子网。不同家庭的路由器,其内网的子网 IP 通常都是一样的(例如都是 192.168.1.1)。子网内的主机 IP 不能重复,但不同子网之间的 IP 可以重复,因为它们被路由器隔离了。
-
多级网络结构:
每一个家用路由器,其实又作为运营商路由器的子网中的一个节点。这样的运营商路由器可能会有很多级(汇聚层、核心层),直到最外层的运营商路由器,其 WAN 口 IP 才是一个真正的公网 IP。
-
NAT 技术:
当子网内的主机需要和外网进行通信时,路由器会将 IP 首部中的源 IP 地址进行替换(将私有 IP 替换成 WAN 口 IP)。这种技术称为 NAT (Network Address Translation,网络地址转换)。
-
公网服务器部署:
如果希望我们自己实现的服务器程序能够在公网上被外部用户访问到,就需要把程序部署在一台具有公网 IP 的服务器上。这样的服务器通常可以在阿里云、腾讯云等云服务商处购买。
地区或者国家IP的分布:https://zh-hans.ipshu.com/country-list
7. 尝试理解公网
真实的网络结构非常复杂,即涉及到划分公网IP的组织,ICANN,还要在全球范围内进行区域划分,比如亚太,北美,欧洲等,又要考虑各个国家内部的ISP代理,整体拓扑非常复杂,我们简化所有过程,简单理解公网即可
附录有关于建设公网的参与者,和职责说明,AI提示词:公网的整个构建过程,需要涉及到谁,各自核心角色和作用是什么?

8. 路由
在复杂的网络结构中, 找出一条通往终点的路线;
唐僧问路例子1
路由的过程, 就是这样一跳一跳(Hop by Hop) "问路" 的过程.
所谓 "一跳" 就是数据链路层中的一个区间. 具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间.

IP数据包的传输过程也和问路一样。
-
当IP数据包,到达路由器时,路由器会先查看目的IP;
-
路由器决定这个数据包是能直接发送给目标主机,还是需要发送给下一个路由器;
-
依次反复,一直到达目标IP地址;
那么如何判定当前这个数据包该发送到哪里呢? 这个就依靠每个节点内部维护一个路由表;
唐僧问路例子2

-
路由表可以使用route命令查看
-
如果目的IP命中了路由表, 就直接转发即可;
-
路由表中的最后一行,主要由下一跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不匹配时,就按缺省路由条目规定的接口发送到下一跳地址。
假设某主机上的网络接口配置和路由表如下:

-
这台主机有两个网络接口,一个网络接口连到192.168.10.0/24网络,另一个网络接口连到192.168.56.0/24网络;
-
路由表的Destination是目的网络地址,Genmask是子网掩码,Gateway是下一跳地址,Iface是发送接口,Flags中的U标志表示此条目有效(可以禁用某些 条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发;
转发过程例1: 如果要发送的数据包的目的地址是192.168.56.3
-
跟第一行的子网掩码做与运算得 到192.168.56.0,与第一行的目的网络地址不符
-
再跟第二行的子网掩码做与运算得 到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送出去;
-
由于192.168.56.0/24正 是与eth1 接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发;
转发过程例2: 如果要发送的数据包的目的地址是202.10.1.2
-
依次和路由表前几项进行对比, 发现都不匹配;
-
按缺省路由条目, 从eth0接口发出去, 发往192.168.10.1路由器;
-
由192.168.10.1路由器根据它的路由表决定下一跳地址;
路由表生成算法(选学)
路由表可以由网络管理员手动维护(静态路由), 也可以通过一些算法自动生成(动态路由).
结论:
- 公网路由器的路由表算法和内网的路由表算法复杂度是不同的
- IP报文可能要进行分片与组装
- 网络通信的过程中,如果过多分片,就会导致丢包概率。
谈一谈在网络通信过程中的分片问题,分片在数据链路层、IP网络层、传输层及应用层的操作分别是什么?分片的最大尺寸是什么?报文大小和MTU的关系。为什么要使用分片?分片和组装不是主流而是被迫为之是为什么?怎样减少分片?减少分片的本质在哪一层,传输层应该交给IP的报文多大的时候,IP不会分片?根据IP报文的16位标识、3位标志、13位偏移学习如何分片和组装:1.甄别特定报文是否被分片了a.更多分片的标志是否是1,1就是分片;b.更多分片的标志是0,但是片偏移>0;2.怎么保证自己把分片收全了?a.相同的标识的分片,聚合在一起;b.怎么保证你收全了?(收不全的话,第一篇丢失,片偏移0,中间丢失,结尾丢失。没有更多分片是0的分片);3.怎样组装:把收到的所有的分片,按照片偏移进行升序排序,片偏移+自身报文长度=下一个分片的片偏移数字
9. 网络通信中的 IP 分片问题全解析(AI生成)
分片是网络通信中为适配不同链路层最大传输单元(MTU) 而产生的数据包拆分机制,核心发生在 IP 网络层 ,数据链路层仅做被动限制,传输层 / 应用层通过主动适配规避分片,组装则仅在目标主机 IP 层完成(路由器不参与组装)。以下结合各层操作、核心参数、分片 / 组装原理、存在问题及优化方案逐一拆解,同时解答标识 / 标志 / 偏移的实际应用问题。
9.1 分片在各层的核心操作
各层对分片的处理遵循 "IP 层独担分片 / 组装,其他层仅适配 / 规避" 的原则,无交叉分片逻辑,具体操作如下:
9.1.1 数据链路层:分片的 "触发源头",仅做被动限制
数据链路层有MTU(最大传输单元) 硬性限制(指链路层帧能承载的最大 IP 数据报长度,不含帧头),不同链路 MTU 固定:如以太网 MTU=1500 字节、PPP 链路 MTU=576 字节、无线 WiFi MTU 通常也为 1500 字节。
- 操作:仅检查接收到的 IP 数据报长度是否超过自身 MTU,不主动分片、不参与组装 ;若超过 MTU 且 IP 头禁止分片标志(DF)=1 ,则直接丢弃数据包,并向源主机返回ICMP 超时报文(告知 MTU 超限);若 DF=0,则将 IP 数据报交给上层 IP 层处理分片。
9.1.2 IP 网络层:分片的 "唯一执行者",也是组装的 "唯一完成者"
IP 层是唯一有权限主动分片 的层级,且仅在源主机 / 中间路由器 触发分片,仅在目标主机 完成组装(路由器只转发分片,不组装,避免路由器性能损耗),核心遵循IPv4 RFC 791 分片规则。
- 分片操作:当 IP 数据报长度超过出接口链路 MTU,且 IP 头 DF=0 时,将原始 IP 数据报拆分为多个分片 ,每个分片长度≤出接口 MTU,且除最后一个分片外,其余分片长度为8 字节的整数倍(适配片偏移的单位要求);每个分片保留原始 IP 头的核心字段(标识、版本、协议、源 / 目的 IP 等),仅修改总长度、标志、片偏移、首部校验和。
- 组装操作:仅在目标主机 IP 层 完成,根据 IP 头的标识、源 / 目的 IP 聚合同一原始报文的所有分片,按片偏移排序后重组为原始 IP 数据报,再交给上层传输层;若超时未收全所有分片,则直接丢弃已接收分片,不通知源主机(IP 层无重传机制)。
9.1.3 传输层:主动 "规避分片",不参与分片 / 组装
TCP/UDP 均不支持分片、不识别分片,传输层仅通过自身机制主动适配 MTU,避免 IP 层分片:
- TCP:支持Path MTU 发现(路径 MTU 发现) ------ 通过设置 IP 头 DF=1,结合 ICMP 超时报文,探测源主机到目标主机整条路径的最小 MTU(PMTU) ,并将MSS(最大分段大小) 设为PMTU - 20 字节(IPv4 头固定长度),使 TCP 段封装成 IP 数据报后长度≤PMTU,从源头避免 IP 分片;同时 TCP 有重传、有序接收机制,即使偶发分片,也能通过自身机制保证数据完整性。
- UDP:无 Path MTU 发现、无重传机制,若 UDP 报文封装成 IP 数据报后超过 MTU,且未手动设置 DF=1,则直接交给 IP 层分片;若分片丢失,整个 UDP 报文失效(UDP 无重传),因此 UDP 通常要求应用层控制报文大小。
- 通用操作:传输层仅将自身数据段(TCP 段 / UDP 报)交给 IP 层,不感知 IP 层是否分片;目标主机 IP 层组装完成后,传输层仅接收完整的 IP 数据报载荷,无分片相关处理逻辑。
9.1.4 应用层:分片的 "终极规避",控制报文原始大小
应用层是数据的产生源头,无分片 / 组装能力,仅通过主动控制报文大小,从源头减少传输层 / TCP/UDP 的分片概率:
- 操作:根据业务场景控制发送报文的大小,如基于 TCP 的应用(HTTP/HTTPS/FTP)通常将应用层报文拆分为 ≤MSS 的块,交给 TCP 层;基于 UDP 的应用(DNS/TFTP)严格控制报文大小≤512 字节(封装后 IP 数据报≤576 字节,适配低 MTU 链路),避免 IP 层分片。
9.2 分片的核心基础:最大尺寸、MTU 与报文大小的关系
9.2.1 分片的最大尺寸:单分片长度≤出接口链路 MTU,且非最后分片为 8 字节整数倍
- 单分片最大长度:由出接口链路 MTU 决定,即每个分片的总长度(IP 头 + 载荷) ≤MTU;
- 非最后分片的硬性要求:长度必须是8 字节的整数倍 (因为片偏移的单位是8 字节,确保分片偏移的连续性,避免重组后数据缺失);
- 最后分片:无 8 字节整数倍要求,长度可任意(≤剩余未拆分数据长度)。
9.2.2 报文大小和 MTU 的核心关系
MTU 是链路层对 IP 数据报的 "长度天花板",IP 数据报(报文)大小与 MTU 的关系直接决定是否触发分片,核心公式:
IP数据报总长度(字节)=IP首部长度+传输层载荷长度(TCP段/UDP报)
- 若 IP 数据报总长度 ≤ 出接口 MTU:不触发分片,直接通过数据链路层封装传输;
- 若 IP 数据报总长度 > 出接口 MTU:分两种情况 ------IP 头 DF=1 则丢弃并返回 ICMP;DF=0 则 IP 层分片后传输。
- 关键注意点:MTU 是IP 数据报的最大长度,不含数据链路层的帧头 / 帧尾(如以太网帧头 14 字节 + 帧尾 4 字节,MTU=1500 字节表示帧的 IP 数据报部分最大 1500 字节,整个帧的最大长度 = 14+1500+4=1518 字节)。
9.3 为什么要使用分片?------ 解决跨链路 MTU 不兼容问题
互联网由多种不同链路(以太网、PPP、无线、光纤等)组成,不同链路 MTU 各不相同,而 IP 层的核心目标是实现跨网络的数据包传输 ,分片是 IP 层为适配异构链路 MTU 差异设计的 "兼容机制":
- 若无分片机制,大尺寸 IP 数据报无法在低 MTU 链路上传输,不同链路之间将无法互通,IP 层的跨网络传输能力将失效;
- 分片让 IP 数据报能 "拆分成小块" 通过低 MTU 链路,再在目标主机重组为原始报文,保证了异构网络的互联互通,是 IP 层 "尽力而为" 传输的重要体现。
9.4 分片和组装不是主流而是被迫为之的原因
分片是 IP 层的 "兼容方案",而非 "优化方案",实际网络中尽量规避分片 ,核心原因是分片存在性能损耗、可靠性低、资源浪费三大问题,具体如下:
- 性能损耗大:分片 / 组装消耗主机资源,路由器转发效率降低
- 源主机需要拆分数据包,修改多个 IP 头字段;目标主机需要聚合、排序、重组分片,消耗 CPU / 内存资源;
- 中间路由器需要转发多个分片(原始 1 个包变多个包),增加了路由器的转发压力,降低了整体网络传输效率。
- 可靠性极低:一分片,丢一个就全丢,且无补救机制
IP 层是无连接、不可靠的,无分片重传、分片超时通知机制:
- 同一原始报文的任意一个分片丢失,目标主机 IP 层就无法完成组装,会直接丢弃所有已接收分片,整个原始报文失效;
- 若为 UDP 报文:分片丢失则整个 UDP 报文失效,UDP 无重传机制,只能由应用层重传;
- 若为 TCP 报文:虽 TCP 有重传机制,但分片丢失会导致 TCP 重传整个原始报文,而非丢失的分片,造成带宽资源严重浪费。
- 增加网络拥塞风险:分片增多,网络包数量翻倍
一个大的 IP 数据报分片后会变成多个小分片,网络中传输的包数量翻倍,增加了网络拥塞的概率,且分片更容易被路由器在拥塞时丢弃(路由器通常优先丢弃小数据包)。
- 安全风险:分片攻击的温床
攻击者可利用 IP 分片机制发起分片攻击(如 Teardrop 攻击、Ping of Death 攻击),通过构造畸形分片(如片偏移重叠、分片长度超限),导致目标主机 IP 层组装时内存溢出、系统崩溃,影响主机安全性。
9.5 如何减少分片?减少分片的本质在哪个层级?
- 减少分片的核心方法:从源头规避 远优于事后分片,分三级优化,层层递进
(1)应用层:控制原始报文大小,终极规避
- 基于 UDP 的应用:严格控制报文大小≤512 字节(封装后 IP 数据报≤576 字节,适配所有链路的最小 MTU),如 DNS 协议的 UDP 报文默认≤512 字节;
- 基于 TCP 的应用:避免发送超大应用层报文,按TCP MSS 拆分报文,如 HTTP/HTTPS 的TCP 分段通常≤1460 字节(MSS=1460)。
(2)传输层:利用协议机制主动适配,核心规避
- TCP:开启Path MTU 发现(PMTUd) (操作系统默认开启),通过设置 IP 头 DF=1,结合 ICMP 超时报文探测路径最小 MTU,将MSS 设为PMTU - IPv4 头长度(20 字节),使 TCP 段封装后 IP 数据报长度 = 20+MSS=PMTU,从源头避免 IP 分片;
- UDP:手动设置 IP 头 DF=1,若触发 ICMP MTU 超时报文,则由应用层减小报文大小后重传;避免发送超大 UDP 报文(如>1500 字节)。
(3)网络层:仅做兜底配置,不主动依赖
- 尽量使用以太网等大 MTU 链路(MTU=1500),减少跨链路 MTU 差异;
- 对必须分片的场景,确保 IP 层分片规则合规(非最后分片 8 字节整数倍),避免畸形分片。
- 减少分片的本质:在传输层 (核心)+应用层(终极),而非 IP 层
IP 层是分片的 "执行者",而非 "问题根源",减少分片的本质是让传输层的载荷封装成 IP 数据报后,长度≤路径最小 MTU(PMTU) ,而这个适配过程的核心在传输层:
- TCP 通过MSS 适配 PMTU,是减少分片的核心层级(互联网中大部分数据为 TCP 数据,MSS 机制从源头规避了 99% 的分片);
- 应用层是终极层级,控制原始报文大小,避免传输层产生超大载荷,是对传输层的补充;
- IP 层仅做兜底,无法从本质上减少分片(IP 层分片是 "被动处理",而非 "主动规避")。
9.6 传输层应该交给 IP 的报文多大时,IP 不会分片?
核心结论:传输层载荷长度 ≤ 路径最小 MTU(PMTU) - IP 首部长度,此时 IP 数据报总长度 = IP 头长度 + 传输层载荷长度 = PMTU,≤所有链路 MTU,IP 层不会分片。
1.通用默认值(以太网环境,最常用)
以太网是互联网最主流的链路,MTU=1500 字节,IPv4 头固定长度为 20 字节(无选项字段,操作系统默认),因此:
传输层最大载荷长度=1500−20=1480字节
- TCP:MSS(最大分段大小)=1480 字节(若 TCP 头为 20 字节,则 TCP 实际数据部分 = 1480-20=1460 字节,这是以太网中 TCP 的默认 MSS 值,也是最常见的 "无分片阈值");
- UDP:UDP 报总长度≤1480 字节(UDP 头 8 字节,则 UDP 数据部分≤1472 字节),封装后 IP 数据报 = 20+1480=1500 字节,刚好适配以太网 MTU,IP 不会分片。
2.适配所有链路的安全值(兜底值)
互联网中所有链路的最小 MTU=576 字节(PPP 链路),IPv4 头 20 字节,因此:
传输层载荷长度≤576−20=556字节
该值为全网无分片安全值,无论跨哪种链路,IP 层都不会分片,适合 UDP 应用(如 DNS、TFTP)。
3.带 IP 选项的情况
若 IP 头包含选项字段(如记录路由、时间戳),IP 首部长度会超过 20 字节(如选项字段 10 字节,IP 头长度 = 30 字节),则:
传输层载荷长度=PMTU−实际IP首部长度
(需保证 IP 头长度为 4 字节的整数倍,符合 IHL 字段要求)。
9.7 基于 IP 头标识 / 标志 / 片偏移的分片与组装实战
IP 头的16 位标识、3 位标志、13 位片偏移 是分片 / 组装的核心三元组,所有分片逻辑均围绕这三个字段展开,先明确字段定义,再拆解分片 / 组装的具体步骤,同时解答甄别分片、收全分片、重组分片的问题。
前置:核心三元组字段定义(IPv4 标准)
- 16 位标识(Identification) :源主机为每个原始 IP 数据报分配的唯一序列号 (每发送一个数据报,标识值 + 1),同一原始报文的所有分片,标识值完全相同;源 / 目的 IP + 标识,可唯一确定一个原始 IP 数据报(避免不同报文分片混淆)。
- 3 位标志(Flags) :仅后两位有效,第一位为保留位(必须 = 0):
- DF 位(第二位,禁止分片):0 = 允许分片,1 = 禁止分片(超过 MTU 则丢弃);
- MF 位(第三位,更多分片):1 = 当前分片不是最后一个,后面还有分片;0 = 当前分片是最后一个分片(或原始报文未分片)。
- 13 位片偏移(Fragment Offset) :表示当前分片在原始 IP 数据报中的相对偏移位置 ,单位为 8 字节;实际偏移字节数 = 片偏移值 ×8;13 位最大取值 = 8191,因此最大偏移字节数 = 8191×8=65528 字节,适配 IPv4 最大数据报长度 65535 字节。
1.如何甄别一个 IP 数据报是否被分片?(两种判定条件,满足其一即为分片)
如你所述,通过MF 位 + 片偏移 组合判定,无其他判定条件,核心逻辑:未分片的报文,MF=0 且片偏移 = 0,只要偏离此状态,即为分片:
- 条件 a:MF 位 = 1:直接判定为分片(当前是中间分片,后面还有分片);
- 条件 b:MF 位 = 0,但片偏移>0:判定为分片(当前是最后一个分片);
- 反例:MF=0 且片偏移 = 0:未分片(原始报文直接传输)。
2.如何分片?(源主机 / 路由器的分片步骤,结合三元组)
以原始 IP 数据报总长度 = 2000 字节(IP 头 20 字节,载荷 1980 字节) 、出接口 MTU=1500 字节 、DF=0为例,拆解分片步骤(以太网环境,最典型场景):
步骤 1:计算可拆分的载荷长度
MTU=1500 字节,IP 头 20 字节,因此每个分片的最大载荷长度 = 1500-20=1480 字节 ;且非最后分片载荷长度为8 字节整数倍(1480 是 8 的整数倍,符合要求)。
步骤 2:拆分原始载荷,确定分片数量和各分片载荷长度
原始载荷 = 1980 字节,按 1480 字节拆分:
-
分片 1:载荷 = 1480 字节(8 的整数倍),剩余载荷 = 1980-1480=500 字节;
-
分片 2:载荷 = 500 字节(最后一个分片,无 8 字节要求);
共生成 2 个分片,均满足
分片总长度(20 + 载荷)≤1500 字节。
步骤 3:设置每个分片的 "三元组"+ 其他 IP 头字段
- 分片 1(中间分片):标识 = 原始值,DF=0,MF=1 ,片偏移 = 0(无偏移),总长度 = 20+1480=1500,重新计算首部校验和;
- 分片 2(最后分片):标识 = 原始值(与分片 1 相同),DF=0,MF=0 ,片偏移 = 1480÷8=185,总长度 = 20+500=520,重新计算首部校验和;
步骤 4:将分片交给数据链路层封装传输,各分片独立转发(路由器无关联)。
3.如何保证收全所有分片?(目标主机的收全判定逻辑,含丢失场景处理)
目标主机 IP 层通过 "标识聚合 + MF 位判定 + 超时机制" 保证收全分片,无专门的 "收全确认" 机制,核心逻辑:同一标识的分片,当收到 MF=0 的最后分片时,即可确定分片总数和总长度,再校验是否收全所有分片,具体如下:
步骤 1:按 "源 IP + 目的 IP + 标识" 聚合分片,建立临时组装缓冲区
目标主机为每个唯一的(源 IP + 目的 IP + 标识)创建组装缓冲区,所有属于该原始报文的分片,均存入对应缓冲区,避免与其他报文分片混淆。
步骤 2:通过最后分片(MF=0)确定 "分片总数 + 原始报文总长度"
当收到MF=0 的最后分片 时,通过其片偏移 + 自身载荷长度 计算原始报文的总载荷长度:
原始总载荷长度=最后分片片偏移×8+最后分片载荷长度
再结合各分片的载荷长度,即可确定分片总数(如上述例子,最后分片片偏移 = 185,载荷 = 500,总载荷 = 185×8+500=1480+500=1980,与原始载荷一致)。
步骤 3:校验缓冲区是否包含所有分片(按片偏移遍历)
根据片偏移的 8 字节单位,遍历0 ~ 最后分片片偏移的所有 8 字节块,检查缓冲区是否存在对应分片:
- 若所有偏移位置的分片均存在:判定为收全,进入组装步骤;
- 若任意偏移位置的分片缺失:判定为未收全。
步骤 4:超时机制兜底,避免缓冲区无限占用
目标主机为组装缓冲区设置超时时间 (通常为 15~30 秒,操作系统默认),若超时未收到 MF=0 的最后分片,或超时未收全所有分片,则直接丢弃缓冲区中所有已接收分片 ,释放内存,且不通知源主机(IP 层无重传 / 通知机制)。
分片丢失的三种场景及处理(均直接丢弃所有分片)
如你所述,分片丢失分为首片丢失、中间分片丢失、最后分片丢失,三种场景均导致组装失败,目标主机无任何补救措施:
- 首片丢失(片偏移 = 0 的分片丢失):无法确定原始报文的协议、传输层端口等核心信息,直接丢弃所有已接收分片;
- 中间分片丢失:存在偏移位置空缺,无法连续重组,超时后丢弃所有分片;
- 最后分片丢失(未收到 MF=0 的分片):无法确定原始报文总长度和分片总数,超时后丢弃所有已接收分片。
4.如何组装分片?(目标主机的重组步骤,核心是 "按偏移排序 + 连续拼接")
组装的核心原则:同一标识的分片,按片偏移 ** 升序排序 ,再将载荷连续拼接,恢复原始 IP 数据报,如你所述,片偏移 + 自身报文长度 = 下一个分片的片偏移数字(8 字节单位),具体步骤如下:
步骤 1 :对组装缓冲区中的分片,按片偏移值升序排序
确保分片按原始报文的偏移顺序排列(如分片 1 片偏移 = 0→分片 2 片偏移 = 185→分片 3 片偏移 = 370,依此类推)。
步骤 2:验证分片的连续性(核心:前一个分片的片偏移 + 前一个分片载荷长度 ÷8 = 后一个分片的片偏移)
即你提到的片偏移 + 自身报文长度 = 下一个分片的片偏移 (注:此处 "自身报文长度" 指载荷长度,且需 ÷8 转换为片偏移单位),验证连续性避免分片重叠 / 空缺:
以上述例子为例:
-
分片 1 片偏移 = 0,载荷长度 = 1480→1480÷8=185→0+185=185 = 分片 2 的片偏移,连续;
若验证不连续(如偏移重叠、空缺),则判定为畸形分片,丢弃所有分片。
步骤 3 :连续拼接所有分片的载荷部分,恢复原始载荷
将排序后的分片载荷按顺序拼接,得到原始 IP 数据报的载荷(如分片 1 载荷 1480 字节 + 分片 2 载荷 500 字节 = 1980 字节,与原始载荷一致)。
步骤 4:重构原始 IP 数据报,交给传输层
用首片的 IP 头 (保留原始标识、协议、源 / 目的 IP 等核心字段),替换总长度为原始 IP 数据报总长度,重置 MF=0、片偏移 = 0,重新计算首部校验和,再将拼接后的原始载荷封装进去,得到完整的原始 IP 数据报,最后交给上层传输层处理。
9.8 补充:IPv6 对分片的改进(无中间路由器分片,仅源主机分片)
IPv6 彻底摒弃了中间路由器分片 的机制,仅允许源主机 分片,且 IPv6 头无 DF 位(默认禁止中间路由器分片),进一步减少分片带来的问题:
- 若中间路由器发现 IPv6 数据报超过出接口 MTU,则直接丢弃,并向源主机返回ICMPv6 路径 MTU 超时报文;
- 源主机通过ICMPv6 报文探测路径 MTU,在发送前完成分片,避免中间路由器的性能损耗;
- IPv6 的分片字段移至扩展头中,而非主头,简化了主头结构,提高了转发效率。
9.9 总结
- 分片的核心:仅 IP 层分片 / 组装,其他层仅适配 / 规避,数据链路层 MTU 是触发源头;
- 分片的痛点:可靠性低、性能损耗大,因此是 "被迫为之",实际网络中通过传输层 MSS/PMTU 发现从源头规避;
- 无分片的核心阈值:传输层载荷≤PMTU-IP 头长度,以太网默认 1480 字节,全网安全值 556 字节;
- 分片 / 组装的关键:IP 头标识(唯一聚合)、MF 位(判定最后分片)、片偏移(排序拼接),目标主机通过 "聚合 + MF 位 + 超时" 收全分片,按偏移升序组装,丢失任意分片则整体失效。