127 lines
5.8 KiB
Markdown
127 lines
5.8 KiB
Markdown
---
|
||
tags: [计算机网络, 数据封装, 网络分层]
|
||
create time: 2026-05-17 22:20
|
||
---
|
||
|
||
# 数据封装与解封装
|
||
|
||
## 概述
|
||
|
||
数据在发送端逐层加上头部(Header),就像装快递盒子:最里层是商品,外面一层一层套纸箱、贴面单、打托盘。到达接收端后,每一层剥掉自己的那层包装,只把原始内容交给上层处理。这个"套娃+拆箱"的过程就是 **封装(Encapsulation)** 和 **解封装(Decapsulation)**。
|
||
|
||
> [!QUESTION] 为什么每层都要加头?
|
||
> 因为每层需要知道如何管理自己的事务——传输层关心连接状态,网络层关心路由寻址,链路层关心物理介质。这些元信息必须跟在数据前面,让每一层都能正确解读并转发。
|
||
|
||
## 数据包尺寸变化轨迹
|
||
|
||
以发送一个 HTTP GET 请求为例,追踪尺寸变化:
|
||
|
||
| 层级 | 操作 | 数据结构 | 新增首部大小 | 累计大小 |
|
||
|------|------|---------|-------------|---------|
|
||
| 应用层 | HTTP GET 报文 | `GET / HTTP/1.1\r\nHost: example.com\r\n\r\n` | — | ~40 bytes |
|
||
| 传输层 (TCP) | + TCP Header | Segment | 20 bytes | ~60 bytes |
|
||
| 网络层 (IP) | + IP Header | Packet | 20 bytes (IPv4) | ~80 bytes |
|
||
| 链路层 (Ethernet) | + Eth Header + FCS | Frame | 14 + 4 = 18 bytes | ~98 bytes |
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
H["HTTP GET 40B"] --> T["+ TCP Header 20B<br/>Segment 60B"]
|
||
T --> I["+ IP Header 20B<br/>Packet 80B"]
|
||
I --> E["+ Ethernet HDR 14B + FCS 4B<br/>Frame 98B"]
|
||
E --> B["98 个 Bit 在网线上传输"]
|
||
|
||
style H fill:#DDA0DD
|
||
style T fill:#FFD700
|
||
style I fill:#87CEEB
|
||
style E fill:#98FB98
|
||
```
|
||
|
||
## 发送端:逐层封装
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant App as HTTP 应用
|
||
participant TCP as TCP Socket
|
||
participant IP as 网络层 IP
|
||
participant ETH as 以太网驱动
|
||
|
||
App->>TCP: write("GET / HTTP/1.1...")
|
||
Note over TCP: 分配 seq/ack, state=ESTABLISHED
|
||
TCP->>IP: 传递 Segment (daddr=x.x.x.x, sport=1234, dport=80)
|
||
Note over IP: 查路由表 → 下一跳网关
|
||
IP->>ETH: 传递 Packet (dst_mac=?, src_ip=192.168.1.100, dst_ip=93.184.216.34)
|
||
Note over ETH: ARP 解析 → dst_mac=aabb.ccdd.eeff
|
||
ETH->>ETH: 拼接 源MAC+目的MAC+EtherType+Payload+FCS
|
||
ETH-->>App: sendto() 返回 → 帧已发出 ✅
|
||
```
|
||
|
||
### Ethernet II 帧完整结构
|
||
|
||
```
|
||
Offset Size Field 说明
|
||
────── ──── ───────────────── ─────────────────────────────
|
||
0 6 Dest MAC Address 目标 MAC 地址
|
||
6 6 Source MAC Address 源 MAC 地址
|
||
12 2 EtherType 0x0800=IPv4 / 0x86DD=IPv6 / 0x0806=ARP
|
||
14 N Payload IP 包(最大 1500 字节)
|
||
14+N 4 FCS CRC-32 帧校验序列(接收端自动验证)
|
||
```
|
||
|
||
总长度范围:**64 ~ 1518 bytes**(不含 VLAN Tag;有 VLAN Tag 则上限 1522)。
|
||
|
||
> [!note] MTU = 1500 是什么意思?
|
||
> MTU(Maximum Transmission Unit)是链路层允许的最大 Payload 大小,即 IP 包的最大体积。超过会被分片(Fragmentation),但分片会降低性能且增加丢包风险——这也是现代应用层(如 TLS、gRPC)倾向于小包传输的原因。
|
||
|
||
## 接收端:逐层解封装
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant ETH as 网卡收到 Frame
|
||
participant IP as 剥离以太网头
|
||
participant TCP as 剥离 TCP 头
|
||
participant App as 提取 HTTP 数据
|
||
|
||
ETH->>IP: 校验 FCS OK → 取 EtherType=0x0800 → 剥离以太网头
|
||
IP->>TCP: 校验 IP Checksum → 取 Protocol=6(TCP) → 剥离 IP 头
|
||
TCP->>App: 按 Sequence Number 重组 → 剥离 TCP 头
|
||
App->>App: 解析 "GET / HTTP/1.1..." 🎉
|
||
```
|
||
|
||
每层的动作可以概括为三步:
|
||
|
||
1. **检查**:校验和是否正确?mac/ip/port 是否指向自己?
|
||
2. **剥离**:去掉本层的 Header(必要时 Tail 如 FCS)
|
||
3. **移交**:将剩余的 Payload 交给上层协议处理
|
||
|
||
## 各层 PDU 对照表
|
||
|
||
| OSI 名称 | PDU | TCP/IP 对应 | 关键标识字段 |
|
||
|----------|-----|-------------|-------------|
|
||
| 数据 (Data) | 报文段 | 应用层消息 | — |
|
||
| 段 (Segment) | TCP Segment | 传输层 PDU | 源端口 + 目的端口 |
|
||
| 包 (Packet) | IP Datagram | 网络层 PDU | 源 IP + 目的 IP + Protocol |
|
||
| 帧 (Frame) | Ethernet Frame | 链路层 PDU | 源 MAC + 目的 MAC + EtherType |
|
||
| 比特流 (Bits) | Bitstream | 物理层信号 | 电信号 / 光脉冲 |
|
||
|
||
## NAT 场景下的封装变化
|
||
|
||
NAT 路由器修改了中间层的地址:
|
||
|
||
```
|
||
发送端内部主机 NAT 路由器 外部 Web 服务器
|
||
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
|
||
│ Src IP: 10.0.0.5:45678 │ │ SNAT: 改写 Src IP │ │ Dst IP: 203.0.113.1:80 │
|
||
│ Dst IP: 203.0.113.1:80 │ → │ │ → │ │
|
||
│ │ │ → Src IP: 8.8.8.8:45678 │ │ ← Src IP: 203.0.113.1:80 │
|
||
│ │ │ → Dst IP: 203.0.113.1:80 │ │ → Src IP: 10.0.0.5:45678 │
|
||
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘
|
||
```
|
||
|
||
注意:NAT 不触碰应用层载荷,只是在中途修改了 IP 和 TCP 端口。这也意味着 **传输层的 Checksum 需要重新计算**。
|
||
|
||
## 关联笔记
|
||
|
||
- [[hhs/NETWORK/OSI与TCP-IP模型对比]] — 分层模型的起源与对比
|
||
- [[hhs/NETWORK/IPv4协议详解]] — IP 包的详细格式
|
||
- [[hhs/NETWORK/TCP状态机详解]] — TCP 段的结构与状态管理
|