数据链路层

数据链路层

数据链路层位于物理层之上、网络层之下,是 OSI 模型中的第二层。它的核心职责是在相邻节点之间可靠地传输数据帧,解决物理层只负责比特流传输所带来的种种问题。

数据链路层主要解决三大问题:

  1. 封装成帧 --- 将网络层下发的 IP 数据报封装成帧,添加首部和尾部,让接收方能从比特流中识别出帧的边界。
  2. 透明传输 --- 当帧的数据部分出现了与帧定界符相同的字节时,通过字节填充(转义)来避免误判。
  3. 差错检测 --- 利用校验码(如 CRC)检测传输过程中是否出现比特错误,发现错误则丢弃该帧。

数据链路层使用的信道主要有两种类型:

  • 点对点信道:一对一通信,如 PPP 协议(拨号上网、光纤宽带)。
  • 广播信道:一对多通信,如早期的以太网使用 CSMA/CD 协议解决多台主机共享信道的冲突问题。

帧(Frame) 是数据链路层协议数据单元(PDU)的基本单位。网络层下发的 IP 数据报到达数据链路层后,会被封装成一个帧,格式通常为:

复制代码
| 帧首部 | 数据部分(IP 数据报) | 帧尾部 |

帧首部包含目标 MAC 地址、源 MAC 地址、类型/长度等字段;帧尾部通常包含帧校验序列(FCS),用于差错检测。

类比:如果把网络层比作快递的"包裹内容",数据链路层就是给包裹贴上发件地址和收件地址的快递单 ,并加上防拆封条(校验码)。

封装成帧

封装成帧 是指数据链路层在 IP 数据报的前后分别添加帧首部帧尾部,构成一个完整的帧。

为了让接收方能够从连续的比特流中准确识别出帧的起止位置,需要使用帧定界符

  • SOH(Start of Header) :帧起始定界符,十六进制为 01
  • EOT(End of Transmission) :帧结束定界符,十六进制为 04

帧的完整结构示意:

复制代码
SOH  IP数据报(数据部分)  EOT

接收方检测到 SOH 就开始接收数据,遇到 EOT 就认为帧结束。如果数据部分恰好出现了与 SOH 或 EOT 相同的字节,就会导致帧边界误判------这正是下一节"透明传输"要解决的问题。

透明传输

透明传输的含义是:数据链路层对上层(网络层)下发的数据不做任何限制,无论数据中出现什么样的比特组合,都能正确地传输。

问题场景:如果 IP 数据报中恰好包含了一个字节 0x01(与 SOH 相同)或 0x04(与 EOT 相同),接收方就会误以为帧开始或结束,导致帧解析错误。

解决方案:字节填充(转义)

发送方在封装帧时,对数据部分进行扫描:

  • 遇到 SOH0x01),在前面插入一个转义字符 ESC0x1B)。
  • 遇到 EOT0x04),在前面插入一个 ESC
  • 如果数据中本身就有 ESC0x1B),则在它前面再插入一个 ESC

接收方收到后,遇到 ESC 就跳过它,把后面的字节当作普通数据,从而还原出原始数据。

示例:原始数据为 A 0x04 B → 封装后变为 SOH A ESC 0x04 B EOT → 接收方收到后去掉 ESC,还原为 A 0x04 B

差错检测

数据在物理信道上传输时,可能受到电磁干扰、信号衰减等因素影响,导致比特翻转(0 变 1 或 1 变 0)。数据链路层必须有能力检测出这些错误。

循环冗余校验(CRC,Cyclic Redundancy Check) 是最常用的差错检测方法,原理如下:

  1. 发送方和接收方事先约定一个生成多项式 (如 CRC-32 使用 G(x) = x^32 + x^26 + x^23 + x^22 + ... + 1)。
  2. 发送方对数据做模 2 除法,计算出 冗余码(FCS,帧校验序列),附加在数据尾部。
  3. 接收方用同样的生成多项式对收到的数据做除法:
    • 余数为 0 → 传输无误。
    • 余数不为 0 → 传输有误,丢弃该帧。

注意:CRC 只能检测错误,不能纠正错误。检测到错误后,通常由上层协议(如 TCP)负责重传。

CSMA/CD

CSMA/CD(载波监听多点接入/碰撞检测) 是以太网在半双工模式下解决多台主机共享信道冲突的核心协议。虽然现代以太网已全面采用全双工交换网络(交换机隔离冲突域),不再需要 CSMA/CD,但理解它的工作原理对掌握网络基础仍然非常重要。

CSMA/CD 的工作流程可以概括为四个步骤:先听后发 → 边发边听 → 冲突停发 → 随机重发

先听后发

载波监听(Carrier Sense):主机在发送数据之前,先监听信道是否空闲。

  • 如果信道空闲(没有其他主机在发送),就立即发送数据。
  • 如果信道忙碌(有其他主机正在发送),就持续监听,直到信道空闲后再发送。

类比:开会时,你想发言之前先听听有没有人在说话------没人说你就说,有人说你等他说完再说。

边发边听

碰撞检测(Collision Detection) :主机在发送数据的同时,继续监听信道,对比自己发出的信号和线路上实际的信号是否一致。

  • 如果一致 → 说明没有冲突,继续发送。
  • 如果不一致 → 说明发生了碰撞(两个或多个主机同时发送,信号叠加后失真)。

为什么需要边发边听?因为"先听后发"并不能完全避免冲突------可能存在两个主机同时检测到信道空闲并同时开始发送的情况,这就是冲突窗口

冲突停发

一旦检测到冲突,主机立即停止发送数据 ,并发送一个 Jam(阻塞)信号,持续 32 或 48 比特时间。

Jam 信号的作用是强化冲突,让信道上的所有主机都能感知到冲突的发生,从而进入退避等待状态。

随机重发

发生冲突后,各主机不能立即重发,否则会再次冲突。CSMA/CD 使用截断二进制指数退避算法来决定等待时间:

  1. 定义基本退避时间 = 2τ(τ 为单程端到端传播时延,即争用期)。
  2. 定义参数 k = min(重传次数, 10)。
  3. 退避窗口范围:0 ~ (2^k - 1)
  4. 主机在退避窗口内随机选择一个整数 r,等待 r × 争用期 的时间后重试。
  5. 如果重传 16 次仍然失败,则丢弃该帧,向上层报告错误。

退避窗口公式:

复制代码
退避窗口范围:0 ~ (2^k - 1)

例如:第一次冲突(k=1),窗口为 0~1,随机等待 0 或 1 个争用期;第二次冲突(k=2),窗口为 0~3,随机等待 0~3 个争用期。冲突次数越多,等待时间范围越大,冲突概率越低。

最短帧长和争用期

争用期(Contention Period) 是 CSMA/CD 中的核心概念,定义为 ,其中 τ 是信号在信道上从一端传播到另一端所需的时间。

复制代码
A 发送数据 →→→→→→→→→→ B(耗时 τ)
B 检测到冲突 ←←←←←←←←←← A(再耗时 τ)

通俗理解:争用期就是"最晚多久能确定没人跟我抢"的安全时间窗口。

最短帧长:为了保证主机 A 在发送完数据之前能够检测到可能发生的冲突,A 发送的帧必须足够长,长到把整个争用期(2τ)填满。如果帧太短,A 已经发送完毕并停止监听,冲突信号才传回来,A 就无法感知冲突了。

复制代码
最短帧长 = 传输速率 × 争用期(2τ)

以 10 Mbps 的传统以太网为例:

  • 争用期 = 51.2 μs(对应 512 比特时间)
  • 最短帧长 = 10 Mbps × 51.2 μs = 512 比特 = 64 字节

这就是为什么以太网规定最短帧长为 64 字节------任何小于 64 字节的帧都被视为冲突碎片而丢弃。