Appearance
数据包的网络之旅:协议栈封装与解封装
2026 大纲 一(二)3 ISO/OSI 参考模型和 TCP/IP 参考模型 的贯通演示篇:把五层模型放到一条真实路径上跑一遍。分层原理、协议/服务/接口三概念、OSI 与 TCP/IP 对比在《体系结构与参考模型》。
一、静态的分层表回答不了的问题
上一节把每层负责什么说清楚了,但那是一张静态的职责表。数据真跑起来的时候,问题立刻变得具体:从 A 出发的那个帧,目的 MAC 写的是 B 吗?路上经过交换机和路由器,首部里哪些字段变了、哪些一个比特都不能动?
这些问题的答案不在职责表里,只能把一份数据放到一条真实路径上跑一遍才看得见。这一节就干这件事——它不引入任何新概念,全部素材都是上一节的分层与封装,但跑完之后,后面几章里所有"求某一跳上的源 MAC、目的 MAC"的题都变成了同一道题。
先记住这一节的骨架,只有一句:封装是穿衣服、解封装是脱衣服,中间设备只解到自己能看懂的那一层。
二、场景
拓扑:主机 A → 交换机 S1 → 路由器 R → 交换机 S2 → 主机 B。A 的默认网关是 192.168.1.1,两侧都是以太网;A 上的浏览器(源端口 1234)向 B 上的 Web 服务器(目的端口 80)发数据。
| 设备 | IP 地址 | MAC 地址 |
|---|---|---|
| 主机 A | 192.168.1.10 | AA:AA:AA:00:00:01 |
| 路由器 R 接口 1(接 A 侧) | 192.168.1.1 | CC:CC:CC:00:00:01 |
| 路由器 R 接口 2(接 B 侧) | 192.168.2.1 | CC:CC:CC:00:00:02 |
| 主机 B | 192.168.2.20 | BB:BB:BB:00:00:01 |
交互可视化
三、发送方的封装
| 层次 | 数据块变化 | 本层加了什么 | 为了解决什么问题 |
|---|---|---|---|
| 应用层 | [数据] | 无 | 产生要传的内容,PDU 叫报文 |
| 运输层 | [TCP头][数据] | 源端口 1234、目的端口 80、序号、确认号、校验和 | 交给哪个进程、如何做可靠传输 |
| 网络层 | [IP头][TCP头][数据] | 源 IP、目的 IP、TTL、协议字段、首部校验和 | 送到哪台主机、如何逐跳选路 |
| 数据链路层 | [帧头][IP头][TCP头][数据][FCS] | 源 MAC、目的 MAC、类型字段、FCS | 交给同一链路上的哪个节点、这一跳传坏没有 |
| 物理层 | 01101000… 比特流 | 无(不加控制信息) | 把比特变成信号送上介质 |
每层只加自己的头部,上层的整体一律当作本层的"载荷"——本层不去解释上层内容是什么,这就是分层的实质。链路层不看 IP 头里写了什么,它只负责把这一整块字节送到链路对端。只有数据链路层既加首部又加尾部:FCS 必须放在数据之后,因为接收端要先把整帧收完才有可能算出校验值来比对。
现在到了第一个反直觉的地方。A 要发给 B,第一个帧的目的 MAC 不是 B 的,而是路由器 R 接口 1 的。推导只有三步:
- A 用自己的子网掩码算出目的 IP 192.168.2.20 不在本网段;
- 不在本网段的分组一律交给默认网关,也就是 192.168.1.1;
- 要往网关发帧就得知道网关的 MAC,于是用 ARP 问出
CC:CC:CC:00:00:01。
于是第一个帧的地址组合是 目的 MAC CC:CC:CC:00:00:01(R 接口 1)、源 MAC AA:AA:AA:00:00:01、目的 IP 192.168.2.20、源 IP 192.168.1.10。一句话记住:MAC 写"下一跳交给谁",IP 写"最终送到谁"。

图源:谢希仁《计算机网络》(第 8 版)图 1-17,印刷版 p33。注意中间那一段:路由器只画到第 3 层,且左右两侧的 H₂/T₂ 是两组不同的链路层首尾部。
四、逐跳:三类设备各处理到第几层
| 设备 | 处理到第几层 | 依据什么转发 | 帧头帧尾 | IP 首部 |
|---|---|---|---|---|
| 集线器 | 1 | 不做判断,向所有其他端口放大转发 | 原样 | 原样 |
| 交换机 S1 / S2 | 2 | 目的 MAC,查 MAC 地址表选端口 | 原样 | 原样 |
| 路由器 R | 3 | 目的 IP,查路由表选出接口与下一跳 | 整个替换 | 改 TTL 与首部校验和 |
这张表最值得记的不是三行内容,而是它们的共同判据:"工作在第几层"不是设备贴在身上的标签,而是它的转发决策要读哪一层的字段。 要读哪一层的字段,就必须解封装到哪一层,再往上没有必要——集线器不看任何字段(1 层)、交换机看目的 MAC(2 层)、路由器看目的 IP(3 层)。按这条判据,做 NAT 时必须按端口做决策的设备就得解到第 4 层,尽管它挂着"路由器"的名字。
交换机为什么不改帧
它没换链路。S1 的两个端口在同一个广播域、同一个 IP 网段,帧的"下一跳"根本没有变,它要做的只是选一个端口把整帧原样送出去。所以交换机不产生新的地址组合。
路由器为什么必须整个替换帧首尾部
它换了链路。旧的目的 MAC 是 R 接口 1 的,而这个 MAC 在 B 侧那条链路上根本不存在。所以 R 把旧帧的首尾部整个丢掉,重做一次链路层封装:新源 MAC = 出接口 MAC(CC:CC:CC:00:00:02),新目的 MAC = 下一跳 MAC(目的网络直连时就是目的主机的,否则是下一台路由器入接口的)。FCS 当然也是新算的——路由器不是改几个字节,而是重做了一次封装。
根子在作用域上:MAC 是链路层地址,作用域只有一条链路(一个广播域)。交换机的 MAC 表只记"哪个 MAC 挂在我哪个端口",对别的网段一无所知;一个 MAC 地址跨过路由器就没有意义了。
IP 为什么一个比特都不能改
因为 IP 承载端到端语义。改源 IP 会同时打断三件事:对端会把回复发给路由器,会话根本建不起来;中途的路由器无从按最终目的地选路;运输层伪首部(含源、目的 IP)参与校验和计算,一改必然校验失败。
IP 不变正是"网络层提供主机到主机服务"这句话的具体含义。它和"IP 的转发动作是逐跳的"并不矛盾——动作逐跳,语义端到端:每台路由器只决定下一跳(动作),但源、目的 IP 全程不变(语义)。
不过路由器确实动了 IP 首部里的两处:TTL 减 1(减到 0 就丢弃并回送 ICMP 超时报文,用来防路由环路)、IP 首部校验和重算(它只覆盖 IP 首部,TTL 一变就得跟着变)。TCP/UDP 校验和路由器绝不碰——它覆盖运输层首部、数据与伪首部,是端到端的凭据。NAT 是唯一被迫破例的,代价是自己维护转换表并修补运输层校验和;它不是反例,恰恰是"改 IP 要付出什么"的证据。
五、接收方的解封装
| 步骤 | 层次 | 动作 | 交给上层的依据 |
|---|---|---|---|
| 1 | 物理层 | 把信号还原成比特流、组成帧 | — |
| 2 | 数据链路层 | 校验 FCS;比对目的 MAC 是不是自己;剥去帧首尾部 | 类型字段 0x0800 → 交给 IP |
| 3 | 网络层 | 校验首部校验和;确认目的 IP 是自己;剥去 IP 首部 | 协议字段 6 → 交给 TCP(17 → UDP) |
| 4 | 运输层 | 校验 TCP 校验和;按序号重组;剥去 TCP 首部 | 目的端口 80 → 交给 Web 服务器进程 |
| 5 | 应用层 | 拿到原始数据 | — |
最后一列是三级分用链:类型字段 → 协议字段 → 目的端口,顺序不可颠倒,与发送方的复用正好对称。每层首部里都有一个字段专门回答"载荷交给上面的谁"——没有这三个字段,接收方拿到一串字节根本不知道该按什么格式解释。分层不只是"往上交",还必须"说清楚交给谁"。
这张表里还藏着两条容易被合并的线索。一是每层都要问"这是给我的吗":链路层比目的 MAC、网络层比目的 IP、运输层比目的端口,任何一层对不上就丢弃。二是各层检错互不替代:FCS 覆盖整帧(说明这一跳没传坏)、IP 首部校验和只覆盖 IP 首部、TCP 校验和覆盖运输层首部与数据(说明端到端没坏)。路由器内存出错这类问题,只有端到端的那一道校验能发现——这也是网络层不必做可靠传输的理由之一:端到端的检查本来就省不掉,中间再做一遍纯属重复。
六、一次完整的算例
题:上面的拓扑中,A 向 B 发一个 TCP 报文段,应用层数据 500 B,TCP 首部 20 B,IP 首部 20 B,以太网帧首部 14 B、帧尾 FCS 4 B。求两段链路上的地址与帧总长;若 R → B 一段改用 PPP(首部 4 个字段共 5 B、尾部 2 个字段共 3 B),该段帧总长是多少。
(1)地址演变。 源 IP 与目的 IP 由端到端语义决定,全程不变;MAC 逐段确定,判据是"这一跳的发送方是谁、接收方是谁":
| 链路段 | 源 MAC | 目的 MAC | 源 IP | 目的 IP |
|---|---|---|---|---|
| A → S1 → R | AA:AA:AA:00:00:01(A) | CC:CC:CC:00:00:01(R 接口 1) | 192.168.1.10 | 192.168.2.20 |
| R → S2 → B | CC:CC:CC:00:00:02(R 接口 2) | BB:BB:BB:00:00:01(B) | 192.168.1.10 | 192.168.2.20 |
交换机 S1、S2 不改帧,所以它们不产生新的地址组合——链路段数由路由器个数决定:有 1 台路由器就有 2 段,有
(2)帧总长。 IP 数据报总长是各层首部逐层叠加:
两段都是以太网,所以两段都是 558 B。路由器换的是链路层封装,网络层 PDU 一个字节都没动(TTL 与首部校验和是改值不改长度),所以 540 B 这个数全程都成立,变的只是外面那层壳。
(3)改用 PPP 之后:
边界:若某段链路 MTU 小于 540 B,IP 数据报就必须分片,此时一个网络层 SDU 会变成多个 IP 分组,"网络层 PDU 全程不变"的说法不再成立。准确表述是:在不发生分片的前提下,IP 数据报内容除 TTL 与首部校验和外全程不变。
顺带把两个容易混的动作分开:封装是加首部,每层各加一次,不改变数据本身;分片是把一个数据单元拆成几个,只发生在网络层、只在 MTU 不够时才发生。
本节小结
- 设备解到第几层由它的转发依据在第几层决定,不是设备自身的属性。交换机没换链路所以不改帧;路由器换了链路,必须整个替换帧首尾部(新源 MAC = 出接口、新目的 MAC = 下一跳),并另外改 TTL、重算 IP 首部校验和与 FCS。
- MAC 逐跳变、IP 全程不变:MAC 的作用域只有一条链路,IP 承载端到端语义。改源 IP 会同时打断对端回复、中途选路和运输层伪首部校验和。动作逐跳、语义端到端;TCP/UDP 校验和路由器绝不碰。
- 接收方靠三级分用链:类型字段 → 协议字段 → 目的端口,顺序不可颠倒,与发送方的复用对称。链路段数只数路由器不数交换机;IP 数据报长度不变而帧长随链路技术变化,两者不能混为一谈。
考点速记
本篇没有独立的练习区,这一节本身不单独成题——它讲的是一套贯通全课的方法,真题里被考过的形式全部跟着各自的知识点走,显示在别处的练习区里。练习区比本节内容窄属正常,本节的用法是先在这里把方法学会,再到下面几处去做题:
- 求某一跳上帧的源 MAC 与目的 MAC——这是本方法最直接的用法,也是真题里出现最规整的一类。给一张"主机—交换机—路由器—交换机—主机"的拓扑,问 H1 发出的帧的目的 MAC、H2 收到的帧的源 MAC。动作三步:先判目的 IP 在不在本网段 → 不在则目的 MAC 是网关的 → 过了路由器之后源 MAC 换成它的出接口。题目在以太网与以太网交换机的自学习的练习区。
- 无线链路上的三地址:把同样的方法搬到 802.11 帧上,地址 1/2/3 分别是接收端、发送端与真正的目的(或源)。题目在无线局域网的练习区。
- DHCP、ARP 报文的源目地址:新主机还没有 IP 时,封装 DHCP 报文的 IP 数据报源地址是
0.0.0.0、目的是广播地址255.255.255.255。这类题问的仍是"这一跳的地址怎么填",只是主机处在没有地址的特殊状态。题目在 ARP 与 ICMP 的练习区。 - 设备工作在第几层:给一张拓扑问路由器、交换机、集线器实现的最高功能层,判据就是本节第四部分那一条。题目在体系结构与参考模型的练习区。
- 分层封装的开销计算:数清有几层加了首部再除进去,做法在体系结构与参考模型第七部分。
易错:第一个帧的目的 MAC 不是目的主机的,是默认网关的。只要目的 IP 不在本网段,就一定先交给网关。反过来,如果目的 IP 就在本网段,那才直接填对方的 MAC,中途也不会有路由器。
易错:链路段数只数路由器,不数交换机。
台路由器给出 组(源 MAC,目的 MAC)。把交换机也数进去,答案会多出几组根本不存在的地址。
易错:路由器改 TTL 与 IP 首部校验和,绝不碰 TCP/UDP 校验和。NAT 是被迫破例的那一个,而它必须自己修补运输层校验和——这恰好证明了改 IP 是有代价的。
易错:封装不等于分片。 封装是每层加一次首部,全程都在做;分片只发生在网络层、只在 MTU 不够时才做。"每层都可能分片"是错的。
教材出处
- 谢希仁《计算机网络》(第 8 版)印刷版 p33(图 1-17 及其正文)给出逐层封装的完整描述:第 5 层加上必要的控制信息"就变成了下一层的数据单元",依此类推,"不过到了第 2 层(数据链路层)后,控制信息被分成两部分,分别加到本层数据单元的首部(H₂)和尾部(T₂);而第 1 层(物理层)由于是比特流的传送,所以不再加上控制信息"。
- 同书印刷版 p34 描述路由器的处理层次与重新封装:比特流到达路由器后"就从路由器的第 1 层依次上升到第 3 层。每一层都根据控制信息进行必要的操作,然后将控制信息剥去……当分组上升到了第 3 层网络层时,就根据首部中的目的地址查找路由器中的转发表,找出转发分组的接口,然后往下传送到第 2 层,加上新的首部和尾部,再到最下面的第 1 层,然后在物理传输媒体上把每一个比特发送出去"。"加上新的首部和尾部"这半句就是本篇"帧头被整个替换"的直接依据。
- 同书同页给出信封比喻:数据"每经过一层就包上一个新的信封,写上必要的地址信息。包有多个信封的信件传送到目的站后,从第 1 层起,每层拆开一个信封后就把信封中的信交给它的上一层"。
- 同书印刷版 p80(3.2.2 PPP 协议的帧格式)给出算例中 PPP 帧长的依据:"PPP 帧的首部和尾部分别为四个字段和两个字段",首部第一个字段与尾部第二个字段都是标志字段 F,规定为 0x7E。