数据封装与解封装
基于 HTTP 现代标准 · 核于 2026-06
速查
- 封装(encapsulation):发送方数据自顶向下穿过协议栈,每经过一层就把它当作「载荷」,贴上本层首部(必要时再加尾部),交给下一层。
- 解封装(decapsulation):接收方数据自底向上逐层处理,每层剥掉本层首部/尾部,把剩下的载荷交给上一层——与封装严格镜像。
- PDU(协议数据单元,Protocol Data Unit):某一层「首部 + 载荷」打包后的整体,是该层与对端同层对话的单位。
- 各层 PDU 名称:应用层数据 / 报文(data / message)→ 传输层段 segment(TCP)/ 数据报 datagram(UDP)→ 网络层包 / 分组(packet)→ 数据链路层帧(frame)→ 物理层比特(bit)。
- 首部 header 与载荷 payload:首部装「控制信息」(源 / 目的地址、序号、校验等),载荷是「上层交下来的真正数据」;少数层(如以太网)还有尾部 trailer(放 FCS 校验)。
- 关注点分离:每层只认自己的首部,把下层封装、路由、转发的复杂性藏起来——上层无需关心底下如何传输。
- 同层对话:封装让发送方某层与接收方对应层「逻辑上直接通信」,中间各层只是机械地加 / 剥首部。
- MTU(最大传输单元):链路层一帧能携带的载荷上限,以太网典型值 1500 字节;超过就要在网络层分片(fragmentation)。
- 分片代价:分片会增加首部开销与重组负担,任一分片丢失需整体重传,故现代实践更倾向用 PMTUD(路径 MTU 发现) 提前避免分片。
- 一句话:封装是「层层套信封」,解封装是「层层拆信封」,PDU 名称只是同一坨数据在不同层的「称呼」。
- 边界:本页只讲封装机制与 PDU 名称;各层协议细节见 OSI 七层逐层职责 / TCP/IP 四层与五层教学模型,端到端完整旅程见 一个 HTTP 请求穿越协议栈的端到端旅程。
为什么需要封装
分层模型把通信拆成若干层,但层与层之间靠什么传递数据?答案就是封装。
上层并不直接「调用」下层的功能,而是把自己的整块数据交给下层,对下层说:「帮我把这坨东西送到对端的同层」。下层不关心这坨数据的含义,只把它当作不透明的载荷,在前面加上自己的首部,再交给更下层。如此层层向下,数据像被套进一个又一个信封。
套信封类比
你写好一封信(应用层数据),装进一个写着「房间号」的内层信封(传输层首部 → 段),再套进写着「楼栋地址」的外层信封(网络层首部 → 包),最后交给快递贴上「面单」(链路层首部/尾部 → 帧)。每一层只看自己那层信封上的字,拆到自己负责的那层为止——这就是封装与「关注点分离」。
封装:自顶向下,逐层加首部
发送方数据从应用层出发,每下沉一层就被当作载荷并加上本层首部(链路层还会加尾部)。用一次 HTTP 请求举例,逐层封装示意如下:
应用层 [ HTTP 报文 ] ← data / message
│ 交给传输层,整体作为载荷
▼
传输层 [ TCP头 | HTTP 报文 ] ← segment(段)
│ TCP 段整体作为载荷交给网络层
▼
网络层 [ IP头 | TCP头 | HTTP 报文 ] ← packet(包/分组)
│ IP 包整体作为载荷交给链路层
▼
链路层 [ 帧头 | IP头 | TCP头 | HTTP 报文 | 帧尾 ] ← frame(帧)
│ 整帧编码为信号
▼
物理层 1011010110011010 ... ← bit(比特流)要点:
- 每层只往「最外面」加一层首部,不改动里层内容——里层对外层是「黑盒」。
- 首部里装什么,由该层职责决定:传输层放端口与序号,网络层放源 / 目的 IP,链路层放 MAC 地址与帧校验(FCS,位于尾部)。
- 物理层不再加首部,它的任务是把链路层的帧编码为电 / 光 / 电磁信号,以比特为单位发到线路上。
别把「封装」和 OOP 的封装搞混
网络里的「封装」指给数据加首部这件事,和面向对象编程里「隐藏内部实现」的封装是同名不同义的两个概念,只是都借用了「包起来」的意象。
各层 PDU 名称对照
同一份数据在不同层有不同的正式称呼,这个称呼就是该层的 PDU(协议数据单元)。面试与文档里经常考「网络层的 PDU 叫什么」,务必记牢:
| 层(OSI) | PDU 名称 | 主要新增的首部信息 |
|---|---|---|
| 应用层 | 数据 / 报文(data / message) | 应用协议自身(如 HTTP 头) |
| 传输层 | 段 segment(TCP)/ 数据报 datagram(UDP) | 源 / 目的端口、序号、校验 |
| 网络层 | 包 / 分组 packet | 源 / 目的 IP、TTL、分片标志 |
| 数据链路层 | 帧 frame | 源 / 目的 MAC,尾部 FCS 校验 |
| 物理层 | 比特 bit | 无首部,仅信号编码 |
记忆口诀
数据 → 段 → 包 → 帧 → 比特(自顶向下)。TCP 用「段」、UDP 用「数据报」是初学者最易混的点:段 = TCP 的 PDU,数据报 = UDP 的 PDU。
解封装:自底向上,逐层剥首部
接收方做的事和发送方严格镜像:信号先在物理层还原成比特流与帧,然后自底向上每层剥掉本层首部 / 尾部,按首部指示把载荷交给正确的上层,直到应用层拿到原始 HTTP 报文。
物理层 1011010110011010 ... 把比特流还原成帧
│
▼
链路层 [ 帧头 | IP包 | 帧尾 ] 校验 FCS,剥掉帧头/帧尾 → 取出 IP 包
│
▼
网络层 [ IP头 | TCP段 ] 看目的 IP 确认是本机,剥 IP 头 → 取出 TCP 段
│
▼
传输层 [ TCP头 | HTTP 报文 ] 按目的端口分用到进程,剥 TCP 头 → 取出报文
│
▼
应用层 [ HTTP 报文 ] 应用程序拿到完整数据每层在剥首部时,会先读自己那层的首部做判断:链路层校验 FCS 是否损坏、网络层确认目的 IP 是不是自己、传输层按目的端口把数据分用给对应进程。这正是「每层只认自己的首部」的体现——下层首部对上层已不可见,关注点被层层隔离。
首部 header 与载荷 payload
每个 PDU 都可拆成两部分:
- 首部 header:装控制信息——按 MDN 的定义,包括源 / 目的网络地址、序号信息、差错检测码等「为投递载荷服务」的元数据。
- 载荷 payload:装真正要传的用户数据,即上一层整体交下来的 PDU。长度可变,但受网络协议设定的上限约束。
- 尾部 trailer(部分层才有):如以太网帧把帧校验序列 FCS 放在尾部,用于检测整帧在传输中是否出错。
Wikipedia 对封装的定义点明了本质:封装就是「把该层专属的首部或尾部与一个服务数据单元(即载荷)拼接起来,以便在网络上传输信息」;解封装则是其逆过程,移除下层先前拼接的首部 / 尾部。
MTU 与分片简介
封装时还有一个绕不开的物理约束:MTU(Maximum Transmission Unit,最大传输单元)——链路层一帧能携带的载荷字节上限。以太网典型 MTU 为 1500 字节。
当网络层要发送的 IP 包超过下一跳链路的 MTU 时,就需要分片(fragmentation):把一个大 IP 包拆成多个足够小的分片,各自独立封装成帧上路,到目的主机再按 IP 头里的分片标志重新重组。Cloudflare 文档也提到,IP 首部中就含有「该包是否已被分片」以及包总长度等字段。
分片是「不得已」而非「常态」
- 分片放大了首部开销,并给接收端增加重组负担;
- 任一分片丢失都要整个包重传,对性能不利;
- 因此现代实践普遍使用 PMTUD(Path MTU Discovery,路径 MTU 发现),让发送方提前探测整条路径的最小 MTU,从源头避免分片。
本页只做「封装为什么受 MTU 限制」的概览,TCP 如何据此协商分段大小(MSS)等细节属传输层范畴,不在本页展开。
小结
- 封装 = 自顶向下、层层加首部(必要时加尾部);解封装 = 自底向上、层层剥首部,二者严格镜像。
- PDU 名称自顶向下为:数据 / 报文 → 段(TCP)/ 数据报(UDP) → 包 → 帧 → 比特,是同一份数据在各层的不同称呼。
- 每个 PDU = 首部(控制信息)+ 载荷(上层数据),少数层还有尾部(如以太网 FCS)。
- 每层只认自己的首部,这是分层「关注点分离」在数据传递上的直接落地。
- MTU 限制单帧载荷上限,超限触发分片;分片代价高,现代靠 PMTUD 规避。
延伸阅读:上一页 TCP/IP 四层与五层教学模型 讲清楚了「数据流经哪些层」;理解了本页的「逐层加 / 剥首部」后,下一页 两模型对照与协议归层 会把常见协议精确地放进对应的层里。