组帧
四种组帧方法合为一页。它们要解决的是同一个问题:接收方收到的只是一串比特,怎么知道一帧从哪里开始、到哪里结束,而且帧里的数据恰好长得像定界符时也不出错。 四种方法分别给出了四种答案,真正要会动手算的是零比特填充(2013 年考过),字节填充次之。
机制
为什么要组帧,为什么首尾都要加
发送方依据一定的规则将网络层递交的分组封装成帧,也称组帧。数据链路层之所以要把比特组合成以帧为单位传输,是为了在出错时只重发出错的帧,而不必重发全部数据,从而提高效率。组帧主要解决帧定界、帧同步、透明传输等问题。
组帧时既要加首部,又要加尾部。原因是在网络中信息以帧为最小单位进行传输,接收方收到的是一串比特流,没有首部和尾部就不能正确区分帧。而分组(IP 数据报)只是包含在帧的数据部分里,所以分组不需要加尾部来定界。
实现组帧的方法通常有以下四种。
3.2.1 字符计数法
在帧首部使用一个计数字段来记录该帧所含的字节数(包括计数字段自身所占用的 1 字节)。接收方读出帧首部的字节计数值,就知道后面跟随的字节数,从而确定帧的结束位置;因为帧与帧之间是连续传输的,所以也就能确定下一帧的开始位置。
例如依次收到 5 1 2 3 4 | 5 6 7 8 9 | 8 0 1 2 3 4 5 6 | 8 7 8 9 0 1 2 3,第一个 5 表示第 1 帧共 5 个字符(含 5 本身),于是 5 1 2 3 4 是一帧,接着的 5 开始第 2 帧,依此类推。
这种方法最大的问题是计数字段一旦出错,就失去了帧边界划分的依据:接收方无法判断所传输帧的结束位置和下一帧的开始位置,收发双方将失去同步,造成灾难性后果——一个计数字段错了,后面的每一帧都会被切错。
3.2.2 字节填充法
使用特定字节来定界一帧的开始与结束。例如控制字符 SOH 放在帧的最前面表示帧的开始,控制字符 EOT 表示帧的结束。为了使信息位中出现的特殊字符不被误判为帧的首尾定界符,在特殊字符之前填充一个转义字符 ESC 来加以区分。注意,转义字符是 ASCII 码中的一个控制字符,是一个字符,而不是”E""S""C”三个字符的组合。接收方收到转义字符后,就知道其后面紧跟的是数据信息,而不是控制信息。
| 帧内容 | |
|---|---|
| 网络层发出的数据 | SOH A EOT ESC B EOT |
| 经链路层填充后 | SOH A ESC EOT ESC ESC B EOT |
| 接收方交给网络层 | SOH A EOT ESC B EOT |
数据段中出现 EOT 或 SOH 字符时,发送方在每个 EOT 或 SOH 前再插入一个 ESC;若转义字符 ESC 本身也出现在数据中,解决方法仍是在它前面插入一个转义字符。接收方收到数据后自己删除这个插入的 ESC,仍得到原来的数据。这也正是”字符填充法”名称的由来。PPP 在异步线路上用的就是这种方法,转义字符为 0x7D(3.7.2)。
3.2.3 零比特填充法
零比特填充法允许数据帧包含任意个数的比特,它使用一个特定的比特串 01111110 来标志一帧的开始和结束。为了不使数据字段中出现的比特流 01111110 被误判为帧的首尾标志:
- 发送方先扫描整个数据字段,每遇到 5 个连续的”1”,就自动在其后插入一个”0”;
- 接收方执行逆操作,每收到 5 个连续的”1”,就自动删除后面紧跟的”0”,恢复原始数据。
经过这种比特填充后,就可以保证数据字段中不会出现 6 个连续的”1”,也就不会与标志 01111110 混淆。数据链路层早期使用的 HDLC 协议,便是采用这种比特填充的首尾标志法来实现透明传输的;PPP 在同步线路上也用它。零比特填充法很容易由硬件来实现,性能优于字节填充法。
3.2.4 违规编码法
在物理层进行比特编码时,常采用违规编码法。例如曼彻斯特编码方法将数据比特”1”编码成”高-低”电平对,将数据比特”0”编码成”低-高”电平对,而”高-高”电平对和”低-低”电平对在数据比特中是违规的(没有采用),因此可借用这些违规编码序列来定界帧的起始和终止。局域网 IEEE 802 标准就采用了这种方法——以太网帧不需要结束定界符正是这个道理(3.6.2)。
违规编码法不采用任何填充技术便能实现数据的透明传输,但它只适用于采用冗余编码的特殊编码环境。
四种方法怎么取舍
因为字符计数法中计数字段的脆弱性,以及字节填充法实现上的复杂性与不兼容性,目前较常用的组帧方法是零比特填充法和违规编码法。
计算模板:零比特填充
- 把所有要填充的字节首尾相接成一个比特流——连续的 1 可以跨字节边界。
- 从左往右数连续的 1,数到 5 个就在其后插 0,并把计数清零,从插入的 0 之后重新数。
- 插不插 0 与第 6 位是什么无关:哪怕原数据第 6 位本来就是 0,也要插。
- 首尾标志 01111110 本身不参与填充。
例(2013 真题,王道 3.2.5 第 1 题):HDLC 协议对 01111100 01111110 组帧后,对应的比特串为?
原始:0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0
填充:0 1 1 1 1 1 [0] 0 0 0 1 1 1 1 1 [0] 1 0第一个字节里 5 个 1 之后本来就跟着 0,但仍要插入一个 0;第二个字节是标志图样本身,数到第 5 个 1 后插 0,破坏掉 6 个连续的 1。结果 01111100 00111110 10,选 A。
例(王道 3.2.5 综合应用第 1 题):字符编码 A = 01000111,B = 11100011,ESC = 11100000,FLAG = 01111110,用 FLAG 作首尾标志、ESC 作转义字符,传送 A、B、ESC、FLAG 四个字符:
| 方法 | 实际发送的位序列 |
|---|---|
| 字符计数法 | 00000101 01000111 11100011 11100000 01111110(计数 5 含自身) |
| 字节填充法 | 01111110 01000111 11100011 11100000 11100000 11100000 01111110 01111110 |
| 零比特填充法 | 01111110 01000111 110100011 111000000 011111010 01111110 |
零比特填充那一行的三处插 0 全部跨越了字节边界或落在字符内部:A 末尾的 3 个 1 与 B 开头的 2 个 1 凑成 5 个,在 B 的第 2 位后插 0;B 末尾的 2 个 1 与 ESC 开头的 3 个 1 凑成 5 个,在 ESC 的第 3 位后插 0;FLAG 作为数据时 5 个 1 后插 0。只按字节单独数 1 的话三处都会漏掉。
边界
字符计数法里的计数值包括计数字段自己。 这是读题最容易漏的一点,教材图示里的”5”就是 1 个计数字节 + 4 个数据字节。
字节填充法转义的对象包括转义字符本身。 数据里出现 ESC 也要在前面加一个 ESC,否则接收方会把原本的 ESC 当成转义标记,吃掉它后面的那个字节。
零比特填充只插 0、不插 1,接收方只删 5 个 1 后面的那个 0。 所以线路上永远不会出现 6 个连续的 1——标志 01111110 由此唯一。
违规编码法不需要填充,但不是所有编码都能用。 它依赖编码本身有冗余(曼彻斯特编码每比特用两个电平,才有”违规”组合可用),非冗余编码没有可借的违规序列。
帧要首尾定界,分组不需要。 帧在链路上以比特流形式到达,需要自己定界;IP 数据报装在帧的数据部分里,边界由帧给出,所以 IP 首部里只有”总长度”而没有尾部。
对照速查
| 方法 | 定界手段 | 透明传输 | 缺点 | 实例 |
|---|---|---|---|---|
| 字符计数法 | 首部计数字段 | 天然透明 | 计数出错则全部失步 | — |
| 字节填充法 | SOH / EOT 等特殊字符 | 特殊字符前插 ESC | 实现复杂、不兼容 | PPP 异步线路 |
| 零比特填充法 | 01111110 | 5 个 1 后插 0 | — | HDLC、PPP 同步线路 |
| 违规编码法 | 编码中的违规序列 | 无须填充 | 只适用于冗余编码 | IEEE 802 局域网 |
考点
- 以帧为单位的目的:出错时只重发出错的帧
- 字符计数法:计数含自身;计数字段出错失去同步
- 字节填充法:特殊字符(含 ESC 本身)前插 ESC
- 零比特填充法:5 个 1 后插 0,连续 1 跨字节计数(2013)
- 违规编码法:借用曼彻斯特的”高-高""低-低”,无须填充,802 局域网采用
- 常用的是零比特填充法和违规编码法
链接
- 🏠 返回总览:计算机网络第 3 章:数据链路层总览
- ⬅️ 上一节:3.1 数据链路层的功能
- ➡️ 下一节:3.3.1 检错编码
- 🔗 3.7.2 PPP(两种填充的实际应用)
- 📖 名词库:第 3 章名词库