---
tags: [计算机网络, CSMA-CD, 以太网退避, 冲突检测]
create time: 2026-05-17 23:00
---
# CSMA/CD 与以太网退避
## 概述
CSMA/CD(Carrier Sense Multiple Access / Collision Detection,载波监听多路访问/冲突检测)是早期共享式以太网的 MAC 子层协议。虽然现代交换式以太网已不再使用它,但理解其原理对掌握网络演进和碰撞域概念至关重要。
> [!QUESTION] 为什么需要 CSMA/CD?
> 在共享介质(如同轴电缆或 Hub 集线器)上,多台设备共用同一根网线。如果没有协调机制,两台同时发送会导致信号叠加破坏——就像两个人同时在同一频道说话,谁也听不清。
## CSMA/CD 工作流程
```mermaid
flowchart TD
Start["有帧要发送"] --> Wait["等待信道空闲?"]
Wait -->|"空闲"| Send["开始发送"]
Wait -->|"忙碌"| Wait
Send --> Check{"是否在 512bit
时间内检测到冲突?"}
Check -->|"否"| Done["发送完成 ✅"]
Check -->|"是"| Collide["发生冲突 → 发送 Jam Signal"]
Collide --> Backoff["指数退避算法计算等待时间"]
Backoff --> Retry{"重传次数 < 16?"}
Retry -->|"是"| Wait
Retry -->|"否"| Fail["丢弃帧,上报错误 ❌"]
style Done fill:#98FB98,color:#000
style Fail fill:#FF6B6B,color:#fff
```
### 四个步骤详解
| 步骤 | 英文名称 | 说明 |
|------|---------|------|
| 1 | **Carrier Sense** | 发送前先监听:信道忙就等,空闲才发 |
| 2 | **Multiple Access** | 多个设备共享同一介质 |
| 3 | **Collision Detection** | 发送过程中持续监测是否有冲突信号 |
| 4 | **Collision Handling** | 检测到冲突 → 发 Jam Signal → 执行退避 → 重试 |
## 二进制指数退避算法
冲突后的等待时间通过随机退避来避免再次冲突:
$$\text{等待时间} = \min(r, 2^{10}-1) \times 512 \text{ bit-time}$$
其中 $r$ 为重传次数,`512 bit-time` 是最小帧长对应的传输时间(即争用期)。
```mermaid
flowchart TD
k["重传次数 k"] --> r["r = random(0 ~ 2^k - 1)"]
r --> capped["capped at 2^10 - 1 = 1023 (k > 10)"]
capped --> backoff["backoff_time = r × 512 bit-time"]
style k fill:#DDA0DD,color:#000
style backoff fill:#98FB98,color:#000
```
### 退避表
| 重传次数 k | 窗口大小 2^k - 1 | 可能等待的 slot 数范围 |
|-----------|------------------|---------------------|
| 1 | 1 | {0, 1} |
| 2 | 3 | {0, 1, 2, 3} |
| 3 | 7 | {0..7} |
| 4 | 15 | {0..15} |
| 5–10 | 最大值 1023 | {0..1023} |
| >10 | 仍为 1023 | 上限固定 |
如果重传 16 次仍然失败,帧被丢弃并向上层报告错误。
### 示例
假设节点 A 和 B 同时发送,发生冲突:
```
时刻 0ms: A 和 B 同时发送 → 冲突!
两者都发送 32bit Jam Signal
时刻 0.1ms: A 选 r=3 → 等 3×512bit-time = 3×51.2μs ≈ 154μs
B 选 r=1 → 等 1×51.2μs ≈ 51μs
时刻 0.05ms: B 先等完,先尝试发送 → A 还在等
时刻 0.15ms: A 等完,发现信道已被 B 占用 → 退避重选 r
...
```
## 最小帧长与争用期
### 为什么最小帧是 64 字节?
关键公式:**帧传输时间 ≥ 2 × 端到端传播延迟**
如果帧太短,可能在冲突信号到达之前就已经发完了——发送方根本不知道发生过冲突。
```mermaid
sequenceDiagram
participant A as 节点 A
participant H as 最远节点 H
Note over A,H: 传播延迟 = τ
A->>H: 开始发送一个超短帧 (长度 < 2τ)
H->>A: 冲突信号沿原路返回
Note over A: 此时 A 已经发完了...
没检测到冲突!🔥
```
所以规定:
$$\text{最小帧长} \geq 2 \times \tau \times \text{带宽}$$
对于经典 10Mbps 以太网,最长电缆段 2500m,$\tau \approx 12.5\mu s$:
$$\text{最小帧长} \geq 2 \times 12.5\mu s \times 10^7 \text{ bps} = 250,000 \text{ bits?}$$
等等,实际工程中使用了中继器和更短的网段组合,最终标准定为 **512 bit-time = 64 bytes**。
## 现代以太网中的命运
| 年代 | 拓扑 | 介质 | CSMA/CD? |
|------|------|------|---------|
| 1980s | 总线型 | 同轴电缆 | ✅ 必需 |
| 1990s | 星型 + Hub | 双绞线 | ✅ 存在但极少冲突 |
| 2000s+ | 全双工 Switch | 双绞线/光纤 | ❌ 已禁用 |
全双工模式下,收发通道分离(两根线对),不存在碰撞的可能,CSMA/CD 自动关闭。从 Gigabit Ethernet (802.3ab) 起,交换机端口默认全双工运行。
> [!note] 如何检查当前网卡是否启用了 CSMA/CD?
> ```bash
> $ ethtool eth0 | grep -i coll
> Supports Collision Detection: yes
> Current Collision Detection: disabled (full-duplex)
> ```
## 关联笔记
- [[hhs/NETWORK/Ethernet帧结构]] — 以太网 II 帧的格式定义
- [[hhs/NETWORK/Switch与路由器]] — Switch 如何通过全双工消除冲突
- [[hhs/NETWORK/VLAN与Trunk]] — VLAN 隔离冲突域