139 lines
4.9 KiB
Markdown
139 lines
4.9 KiB
Markdown
|
|
---
|
|||
|
|
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<br/>时间内检测到冲突?"}
|
|||
|
|
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 已经发完了...<br/>没检测到冲突!🔥
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
所以规定:
|
|||
|
|
|
|||
|
|
$$\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 隔离冲突域
|