PPP协议解决数据链路层三个基本问题

作者 Tea-Sun · 2026年10月14日 · 约 5 分钟 · 最后更新于 2026年10月15日

PPP 协议:封装成帧与透明传输#

视频讲解:#

https://www.bilibili.com/video/BV1G2pr6aEsh/(嗒特老师)

一句话讲清#

数据链路层把网络层交下来的 IP 数据报装进「帧」:前后加首部和尾部,尾部带 CRC 校验码,首尾各一个标志字段负责定界。如果数据里恰好出现了跟标志一样的字节,就用填充法把边界藏起来——这就是透明传输。PPP 有两条路:

  • 异步传输 → 字节填充(转义字符 0x7D)
  • 同步传输 → 零比特填充(5 个连续 1 后面插一个 0)

一、封装成帧:把数据报装进信封#

数据链路层以帧为单位传输和处理数据。网络层的 IP 数据报向下交给数据链路层,成为帧的数据部分,在它前面和后面分别加上首部和尾部,封装成一个完整的帧。

  • 帧长 = 数据部分长度 + 首部长度 + 尾部长度
  • 接收方必须能正确识别每个帧的开始和结束——这叫帧定界
  • 首部和尾部的重要作用之一就是帧定界,同时携带必要的控制信息
  • 数据部分的长度有上限,即最大传送单元 MTU

为什么非定界不可?因为物理层只认一串连续的比特流,它不知道哪里是帧的头、哪里是尾。帧的边界是数据链路层自己加出来的。


二、PPP 帧长什么样#

字段 长度 取值 / 含义
标志字段 F 1 字节 0x7E(二进制 01111110)——帧的定界符
地址字段 A 1 字节 固定 0xFF(实际不起作用)
控制字段 C 1 字节 固定 0x03(实际不起作用)
协议字段 2 字节 0x0021 表示信息字段就是 IP 数据报
信息字段 可变 载荷,长度 ≤ 1500 字节
帧检验序列 FCS 2 字节 用 CRC 算出的检错码
标志字段 F 1 字节 0x7E,与首部标志相同
  • PPP 面向字节,所有 PPP 帧的长度都是整数个字节
  • 帧首和帧尾的标志字段相同;连续两个帧之间只需要一个标志字段

三、透明传输:数据"撞上"定界符怎么办#

目标是「透明传输」:数据链路层对上层交下来的数据不挑食——不管里面是什么内容,都能原样传过去,就好像数据链路层不存在一样。

冲突点:标志字段 0x7E 是用来定界的。如果信息字段里恰好也出现了 0x7E,接收方会误以为帧到此结束:

  • 前面那一段被当成一个「完整的帧」收下
  • 后面剩下的数据因为找不到结束标志,被丢弃

解决办法:按链路的传输方式分两套。

3.1 异步传输 → 字节填充(转义字符 0x7D)#

RFC 1662 规定的填充方法:

# 信息字段中出现 发送端变换为 规律
1 0x7E 0x7D 0x5E 前面插转义符,字符异或 0x20
2 0x7D 0x7D 0x5D 转义符自己也要转义
3 小于 0x20 的 ASCII 控制字符 0x7D + 编码改变 例如 0x03 → 0x7D 0x23
  • 规律:异或 0x20。0x7E ^ 0x20 = 0x5E,0x7D ^ 0x20 = 0x5D,0x03 ^ 0x20 = 0x23
  • 发送端填充后,链路上传送的字节数比原来的信息字节数多
  • 接收端做相反的变换,就能正确恢复出原来的信息

3.2 同步传输 → 零比特填充#

同步传输是一连串比特连续传送(面向比特),帧长不必是整数个字节,可以用开销更小的零比特填充:

  • 发送端:扫描整个信息字段,只要发现有 5 个连续 1,就立即填入一个 0 → 保证信息字段里永远不会出现 6 个连续 1,也就不会和标志 01111110 撞车
  • 接收端:先找到标志字段 01111110 确定帧的边界,再扫描比特流,每当发现 5 个连续 1,就把后面那个 0 删掉,还原成原来的数据
  • 通常用硬件实现,处理快

四、两种方式对比#

异步传输 同步传输
链路单位 字节 连续的比特流
定界标志 0x7E 01111110
透明传输方法 字节填充 零比特填充
具体规则 转义字符 0x7D;0x7E→7D 5E,0x7D→7D 5D,<0x20 前置 0x7D 并异或 0x20 5 个连续 1 后插 1 个 0
实现 软件 / 字节处理 硬件,开销更小

五、易错点#

  1. 0x7E 的二进制是 01111110——中间有 6 个连续 1,这就是"5 个 1 后插 0"能防冲突的原因。
  2. 转义符 0x7D 本身也要转义:数据里出现 0x7D → 变成 0x7D 0x5D(别漏)。
  3. 小于 0x20 的控制字符不是简单加个 0x7D,而是加 0x7D 且改变编码(异或 0x20)。
  4. 零比特填充是"5 个连续 1 后插 0",不是 6 个。
  5. 字节填充会让链路上传的字节数变多,但接收端还原后和原始数据完全一致。