数据链路层
数据链路层位于物理层之上、网络层之下,是 OSI 模型中的第二层。它的核心职责是在相邻节点之间可靠地传输数据帧,解决物理层只负责比特流传输所带来的种种问题。
数据链路层主要解决三大问题:
- 封装成帧 --- 将网络层下发的 IP 数据报封装成帧,添加首部和尾部,让接收方能从比特流中识别出帧的边界。
- 透明传输 --- 当帧的数据部分出现了与帧定界符相同的字节时,通过字节填充(转义)来避免误判。
- 差错检测 --- 利用校验码(如 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 相同),接收方就会误以为帧开始或结束,导致帧解析错误。
解决方案:字节填充(转义)
发送方在封装帧时,对数据部分进行扫描:
- 遇到
SOH(0x01),在前面插入一个转义字符 ESC (0x1B)。 - 遇到
EOT(0x04),在前面插入一个 ESC。 - 如果数据中本身就有 ESC (
0x1B),则在它前面再插入一个 ESC。
接收方收到后,遇到 ESC 就跳过它,把后面的字节当作普通数据,从而还原出原始数据。
示例:原始数据为
A 0x04 B→ 封装后变为SOH A ESC 0x04 B EOT→ 接收方收到后去掉 ESC,还原为A 0x04 B。
差错检测
数据在物理信道上传输时,可能受到电磁干扰、信号衰减等因素影响,导致比特翻转(0 变 1 或 1 变 0)。数据链路层必须有能力检测出这些错误。
循环冗余校验(CRC,Cyclic Redundancy Check) 是最常用的差错检测方法,原理如下:
- 发送方和接收方事先约定一个生成多项式 (如 CRC-32 使用
G(x) = x^32 + x^26 + x^23 + x^22 + ... + 1)。 - 发送方对数据做模 2 除法,计算出 冗余码(FCS,帧校验序列),附加在数据尾部。
- 接收方用同样的生成多项式对收到的数据做除法:
- 余数为 0 → 传输无误。
- 余数不为 0 → 传输有误,丢弃该帧。
注意:CRC 只能检测错误,不能纠正错误。检测到错误后,通常由上层协议(如 TCP)负责重传。
CSMA/CD
CSMA/CD(载波监听多点接入/碰撞检测) 是以太网在半双工模式下解决多台主机共享信道冲突的核心协议。虽然现代以太网已全面采用全双工交换网络(交换机隔离冲突域),不再需要 CSMA/CD,但理解它的工作原理对掌握网络基础仍然非常重要。
CSMA/CD 的工作流程可以概括为四个步骤:先听后发 → 边发边听 → 冲突停发 → 随机重发。
先听后发
载波监听(Carrier Sense):主机在发送数据之前,先监听信道是否空闲。
- 如果信道空闲(没有其他主机在发送),就立即发送数据。
- 如果信道忙碌(有其他主机正在发送),就持续监听,直到信道空闲后再发送。
类比:开会时,你想发言之前先听听有没有人在说话------没人说你就说,有人说你等他说完再说。
边发边听
碰撞检测(Collision Detection) :主机在发送数据的同时,继续监听信道,对比自己发出的信号和线路上实际的信号是否一致。
- 如果一致 → 说明没有冲突,继续发送。
- 如果不一致 → 说明发生了碰撞(两个或多个主机同时发送,信号叠加后失真)。
为什么需要边发边听?因为"先听后发"并不能完全避免冲突------可能存在两个主机同时检测到信道空闲并同时开始发送的情况,这就是冲突窗口。
冲突停发
一旦检测到冲突,主机立即停止发送数据 ,并发送一个 Jam(阻塞)信号,持续 32 或 48 比特时间。
Jam 信号的作用是强化冲突,让信道上的所有主机都能感知到冲突的发生,从而进入退避等待状态。
随机重发
发生冲突后,各主机不能立即重发,否则会再次冲突。CSMA/CD 使用截断二进制指数退避算法来决定等待时间:
- 定义基本退避时间 = 2τ(τ 为单程端到端传播时延,即争用期)。
- 定义参数 k = min(重传次数, 10)。
- 退避窗口范围:0 ~ (2^k - 1)。
- 主机在退避窗口内随机选择一个整数 r,等待 r × 争用期 的时间后重试。
- 如果重传 16 次仍然失败,则丢弃该帧,向上层报告错误。
退避窗口公式:
退避窗口范围:0 ~ (2^k - 1)例如:第一次冲突(k=1),窗口为 0~1,随机等待 0 或 1 个争用期;第二次冲突(k=2),窗口为 0~3,随机等待 0~3 个争用期。冲突次数越多,等待时间范围越大,冲突概率越低。
最短帧长和争用期
争用期(Contention Period) 是 CSMA/CD 中的核心概念,定义为 2τ,其中 τ 是信号在信道上从一端传播到另一端所需的时间。
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 字节的帧都被视为冲突碎片而丢弃。