MAC 模块是「帧」这一层的实现:加头、算 CRC、判收、计数。 网管看到的每一个数字都从这里来。
上一节讲 PHY(物理层),这一节讲 MAC(数据链路层)。两者是上下邻居。 这一节要算:CRC 的漏检概率,以及全双工流控的副作用。
一、它做的四件事
成帧:加 14 字节头(目的 6 + 源 6 + 类型 2),末尾加 4 字节 FCS。 算 CRC32:发时算一遍附在末尾,收时算一遍比对。 过滤:目的 MAC 不是自己、不是广播、不是组播就丢掉。 计数:每个端口的收发包数、错误数、丢弃数。网管看到的全从这里来。
二、CRC 能挡住什么
能挡住:任意 32 位以内的突发错误 100%;更长突发的漏检概率是 2 的负 32 次方。 挡不住:整帧丢失、整帧重复、顺序错乱。这些要靠上层协议。
算一下漏检概率:10 亿帧里期望有 0.23 帧「错了但 CRC 对上了」。 千兆线速下 10 亿帧约 11 分钟。
所以 CRC 不是万无一失,但已经够用。真正要端到端保证得靠 TCP 的校验和——两层校验,各管一段。
三、流控的副作用
全双工流控在这里实现:端口堵了就发一个 PAUSE 帧(EtherType 0x8808),让对方暂停一段时间。
PAUSE 帧是「整条链路暂停」,不是「某条流暂停」(后者叫 PFC,要 802.1Qbb)。
所以一开流控,一条慢流能把整条链路拖住。 这就是数据中心里「流控要不要开」一直有争议的原因——不开会丢包,开了会扩散拥塞。
四、动手 Demo:CRC32 的漏检概率
这段算 100 万、10 亿、1 万亿帧三个规模下, 期望有多少帧是「错了但 CRC 对上了」(按 2 的 32 次方分之一估)。
for n in (1e6, 1e9, 1e12):
P(u" %s 帧里,期望有 %.6f 帧是「错了但 CRC 对上了」。"
% (format(int(n), u","), n / 4294967296.0))
实跑输出:
--------------------------------------------------------------------
MAC 模块,成帧、算 CRC、计数
--------------------------------------------------------------------
**MAC 模块是「帧」这一层的实现**:它负责加头、算校验、判收、记账。
**它做的四件事**:
1. **成帧**:加 14 字节头(目的 6 + 源 6 + 类型 2),末尾加 4 字节 FCS。
2. **算 CRC32**:发送时算一遍附在末尾,接收时算一遍比对。
3. **过滤**:目的 MAC 不是自己、不是广播、不是组播就丢掉。
4. **计数**:每个端口的收发包数、错误数、丢弃数——**网管看到的全从这里来。**
**CRC32 能挡住什么、挡不住什么,值得说清**:
· **能挡住**:任意 32 位以内的突发错误 100%;更长突发的漏检概率是 2 的负 32 次方。
· **挡不住**:整帧丢失、整帧重复、顺序错乱——**这些要靠上层协议。**
**算一下漏检概率有多大**:
1,000,000 帧里,期望有 0.000233 帧是「错了但 CRC 对上了」。
1,000,000,000 帧里,期望有 0.232831 帧是「错了但 CRC 对上了」。
1,000,000,000,000 帧里,期望有 232.830644 帧是「错了但 CRC 对上了」。
**每 10 亿帧才可能漏一帧。**千兆线速下 10 亿帧约 11 分钟。
**所以 CRC 不是万无一失,但已经够用。**真正要端到端保证得靠 TCP 的校验和。
**全双工流控也在这里实现**:端口堵了就发一个 PAUSE 帧(EtherType 0x8808),让对方暂停一段时间。
**PAUSE 帧有个副作用要记住**:它是「整条链路暂停」,不是「某条流暂停」(后者叫 PFC,
要 802.1Qbb)。
**所以一开流控,一条慢流能把整条链路拖住**——这就是数据中心里「流控要不要开」一直有争议的原因。
10 亿帧才漏 0.23 帧——这就是「够用」的量化含义。 而千兆线速下 10 亿帧只要 11 分钟,所以长时间运行总会遇到漏检帧。
漏检了会怎样:坏帧被当成好帧收下,交给上层。 IP 层的校验和只有 16 位,也拦不住;最后靠 TCP 的 32 位校验和。 所以三层校验叠加起来,实际漏检概率极低。
「挡不住」那三条要记住:整帧丢失、重复、乱序。 CRC 只保证「内容没变」,不保证「只有一份、顺序对」。这就是为什么需要序列号(TCP)而不只是校验和。
30 秒实验
- 查端口的 FCS 错误计数。
- 看交换机有没有开流控(flow control)。
- 查端口统计里的「runts」与「giants」计数。
常见误区
- 以为 CRC 能发现所有错误。只保证内容没变。
- 开了流控就不丢包。会扩散拥塞。
- 以为流控能按流暂停。PAUSE 是整条链路。
自测三问(点开对答案)
1. MAC 模块做哪四件事? —— 成帧、算 CRC、过滤、计数。 2. CRC32 挡不住什么? —— 整帧丢失、重复、顺序错乱。 3. PAUSE 帧的作用范围是什么? —— 整条链路暂停,不是某条流。下一节:最后看两个接口——AUI 与 MII,它们记录了接口从并行走向串行的过程。
- ☐ (本节完,下一节 02.09.04 AUI与MII)