layering - encapsulation
01. 分层、封装与解封装
0. 本章先解决什么问题
网络协议很多:Ethernet、IP、TCP、UDP、DNS、HTTP、TLS。
如果把它们混在一起学,会很乱。
分层解决的是:
把复杂通信拆成若干层
每层只解决自己的问题
上层不用知道下层全部细节
本章要讲:
- 为什么网络必须分层。
- 每层分别解决什么。
- 封装和解封装如何工作。
- 每层头部里大概有什么。
- 分层如何帮助排障。
先看数据向下发送时如何一层层加头部,接收端又如何一层层拆回来。
这张图怎么读
从左边的应用数据开始看:每往下一层,都会加上本层需要的控制信息,比如端口、IP、MAC 和校验字段;到接收端以后,再按相反方向逐层拆掉。读这张图的重点不是背头部名字,而是理解“每层只承诺自己的那部分语义”:链路层只管相邻节点,IP 只管跨网络寻址,TCP/UDP 才管进程间传输,应用层才解释业务含义。
1. 分层的核心思想
分层不是为了考试画图,而是为了降低复杂度。
每层有三个关系:
向上提供服务
向下使用服务
同层之间遵守协议
例如 TCP:
- 向上给应用提供可靠字节流。
- 向下使用 IP 发送包。
- 和对端 TCP 通过序号、ACK、重传等规则协作。
2. 常见五层模型
| 层 | 主要问题 | 数据单位 |
|---|---|---|
| 应用层 | 应用语义 | message/request/response |
| 传输层 | 进程间传输 | segment/datagram |
| 网络层 | 跨网络寻址和路由 | packet |
| 链路层 | 相邻节点传输 | frame |
| 物理层 | bit 在介质上传输 | bit |
OSI 七层更细,TCP/IP 模型更贴近实际。学习时先用五层模型抓主线。
3. 每层解决什么
应用层:
这个数据对应用来说是什么意思?
比如 HTTP 请求、DNS 查询、邮件、文件传输。
传输层:
这份数据属于哪个进程?是否需要可靠、有序、流控?
典型协议:TCP、UDP。
网络层:
这份包从源主机到目标主机怎么走?
典型协议:IP。
链路层:
相邻设备之间怎么传一帧?
典型协议/技术:Ethernet、Wi-Fi。
物理层:
bit 如何变成电信号、光信号、无线信号?
4. 封装
发送数据时,每层加自己的头部。
应用数据
-> 加 TCP 头
-> 加 IP 头
-> 加 Ethernet 头尾
-> 变成 bit 发送
示意:
每层头部只服务于本层目标。
5. 解封装
接收方反向处理:
收到 frame
-> 链路层检查并取出 IP packet
-> 网络层检查并取出 TCP segment
-> 传输层检查并交给对应端口
-> 应用层解析数据
每层只看自己关心的头部。
这就是为什么抓包时会看到一层套一层。
6. 每层头部里有什么
| 层 | 头部常见信息 |
|---|---|
| 链路层 | 源/目的 MAC、类型、校验 |
| 网络层 | 源/目的 IP、TTL、协议号、分片信息 |
| 传输层 | 源/目的端口、序号、ACK、窗口、校验 |
| 应用层 | 方法、路径、状态码、头字段、业务字段 |
头部是控制信息。payload 是上层数据。
手推:同一份数据在每一层的“身份”会变化
分层最容易被误解成“只是套娃”。更准确地说,每层都给同一份数据加了一个新的身份,让它能在对应范围内被处理。
假设一台主机访问另一个网络里的服务,发送端一路向下时可以这样想:
| 层 | 本层看到的数据 | 本层新增的身份 | 本层只承诺什么 |
|---|---|---|---|
| 应用层 | 请求内容 | 方法、路径、字段、业务语义 | 对端应用能按约定解释 |
| 传输层 | 应用数据 | 源端口、目的端口、序号/校验等 | 交给目标主机上的某个进程 |
| 网络层 | 传输层段 | 源 IP、目的 IP、TTL、协议号 | 找到跨网络路径上的下一跳 |
| 链路层 | IP 包 | 源 MAC、目的 MAC、帧校验 | 当前链路上的相邻节点能收到 |
| 物理层 | 帧的 bit | 信号编码 | bit 能在介质上传出去 |
这里有两个关键推论。
第一,身份有作用范围:
MAC 只对当前这一跳有意义
IP 才跨越多跳保持目标语义
端口只在目标主机上区分进程
应用字段只对应用协议有意义
第二,排障时不要拿错身份解释现象。一个常见错误是:看到目标 IP 正确,就以为本地链路一定能交付;或者看到 TCP 端口开放,就以为 HTTP 路由一定正确。分层的意义就在于把这些判断拆开:每一层都有自己的命名、寻址、校验和失败方式。
7. MTU 和分片直觉
链路层一次能承载的数据有限,叫 MTU。
如果 IP 包太大,可能需要分片,或者在路径上被拒绝。
分片会带来:
- 额外开销。
- 丢一片就影响整个包。
- 排障复杂。
所以实际协议常通过路径 MTU、MSS 等机制控制每次发送大小。
8. 分层的好处和代价
好处:
- 降低复杂度。
- 层与层可以相对独立演进。
- 方便定位问题。
- 应用不用关心每种链路细节。
代价:
- 头部开销。
- 层间复制或转换。
- 抽象泄漏。
- 不同层优化目标可能冲突。
例如应用以为 send 成功就是对方收到,但 OS 和 TCP 只能保证数据进入某个传输流程,不保证对端业务处理。
机制深挖:抽象泄漏时,层与层会互相影响
分层让我们能分开理解系统,但真实网络里,层与层并不是完全隔绝。典型抽象泄漏包括:
| 上层看到的现象 | 下层真实原因 | 为什么会泄漏 |
|---|---|---|
| HTTP 请求偶发超时 | TCP 重传、丢包、拥塞窗口变小 | 应用等待的是完整响应,下层传输延迟会直接暴露 |
| 数据库连接慢 | DNS 慢或 TCP 握手慢 | 应用连接动作包含命名和传输阶段 |
| 文件上传大时失败 | MTU、分片、防火墙丢弃大包 | 应用 payload 大小影响下层包大小 |
| TLS 握手失败 | 时间错误、证书链、SNI、代理拦截 | 安全层依赖时间、域名和路径 |
send 返回成功但对端没处理 | 数据只进入本机缓冲区 | 系统调用成功不等于业务完成 |
所以分层排障不是“只看某一层”,而是:
先定位主要失败层
再检查它依赖的下层前提
最后回到上层语义确认结果
例如“HTTP 504”看起来是应用层状态码,但它往往表达的是代理等待上游超时。你要继续往下问:上游连接是否成功、TCP 是否重传、服务是否排队、DNS 是否解析到正确实例。
9. 分层排障
访问失败时,按层排查:
- 应用层:URL、HTTP、认证、状态码
- 传输层:端口、TCP 连接、超时、重传
- 网络层:IP、路由、NAT、防火墙
- 链路层:网卡、局域网、ARP、交换机
- 物理层:线缆、信号、无线质量
每层都有不同证据:
| 层 | 证据 |
|---|---|
| 应用层 | 日志、状态码、请求体 |
| 传输层 | 端口状态、连接状态、抓包 |
| 网络层 | 路由、ping、traceroute、TTL |
| 链路层 | ARP 表、MAC、网卡状态 |
| 物理层 | 连接状态、信号、错误计数 |
10. 联系实际:为什么“网络问题”太模糊
用户说:
网络不通。
你要拆成:
- 域名能解析吗?
- 解析到哪个 IP?
- IP 是否可达?
- 路由走哪里?
- 目标端口是否开放?
- TCP 握手是否完成?
- TLS 是否成功?
- HTTP 请求是否到达?
- 服务端是否处理?
- 响应是否返回?
分层让“网络不通”变成一串可验证问题。
练习卡:从一条错误信息反推层次
拿到网络错误时,先把它翻译成层次,而不是翻译成情绪。
| 现象 | 优先归属层 | 先验证什么 | 不要直接跳到 |
|---|---|---|---|
| 域名解析失败 | 应用层 / DNS | 查询结果、DNS 服务器、缓存 | TCP 拥塞 |
| 连接被拒绝 | 传输层 / 应用监听 | 目标端口是否监听、地址是否正确 | 物理链路坏了 |
| 能连接但返回 404 | 应用层 | 路径、路由规则、虚拟主机 | IP 路由 |
| 大包传输失败,小包正常 | 链路层 / 网络层边界 | MTU、分片、路径变化 | 应用逻辑 |
| 同网段机器互相不通 | 链路层 / ARP | MAC 学习、ARP 表、交换机/VLAN | HTTP |
练习方式:把一个完整 URL 访问画成五层栈,从上到下写出每层新增的头部信息,再从下到上写出每层会丢弃或读取哪些信息。你会发现“封装”不是抽象名词,它决定了错误应该在哪一层被解释。
11. 学完本章你能解决什么问题
学完这一章,你应该能解决或开始分析这些问题:
- 为什么网络要分层?
- 五层模型每层解决什么问题?
- 封装和解封装如何发生?
- 每层头部为什么只服务本层目标?
- MTU 为什么会限制包大小?
- 分层有什么代价?
- 如何按层排查连接失败或请求慢?
分层是网络学习的骨架。只要你能把现象定位到某一层,问题就已经缩小了一大半。