Appearance
介质访问控制:CSMA/CD、CSMA/CA
概念
介质访问控制(Medium Access Control,MAC)就是"多个站点共用同一条广播信道时,约定好谁先发、撞了怎么办"的那一套规则。
一句话说清它是什么:介质访问控制 = 共享信道的"发言规则"——一条总线上挂着十几台机器,它保证"同一时刻只有一个人在说话",或者"撞上了大家都能发现并重新排队"。
它要解决三个问题:
| 问题 | 含义 |
|---|---|
| 谁有权发 | 多个站同时想发, 谁先发 |
| 怎么发现冲突 | 两个站同时发, 如何知道"撞了" |
| 撞了怎么办 | 重发要等多久才能避免再次相撞 |
两大类方法(必背分类):
text
介质访问控制
├─ 静态划分信道 —— 事先把信道切开, 每人一份
│ 频分 FDM / 时分 TDM / 码分 CDM / 波分 WDM (见 net/10-physical.md)
│ 特点: 不会冲突, 但"低负载时严重浪费"
│
└─ 动态接入 —— 用时才申请, 不用时别人可以拿
├─ 随机接入 (争用型): ALOHA / CSMA / CSMA-CD / CSMA-CA
│ 特点: 可能冲突, 但轻负载时效率高
└─ 受控接入: 轮询 (polling) / 令牌传递 (token passing)
特点: 不冲突, 时延有确定上界, 但需要一个控制点⚠️ "随机接入"的名字有点反直觉:它不是"随便发",而是"不事先分配、想发的时候先听一听再发"——"随机"指的是"什么时候有人发是随机的",所以"冲突也是随机的"。
⚠️ 本章与上一章(
net/22-window.md)的分工:上一章解决"帧会不会丢"(可靠传输),假设"信道是独占的";本章解决"多个站怎么共享信道"——两者合起来才是"数据链路层"的两大功能(介质访问 + 可靠传输)。
原理
一、静态划分信道:不冲突,但浪费
静态划分的做法(对照 net/10-physical.md):
| 方式 | 分什么 | 用户数固定时的表现 |
|---|---|---|
| FDM | 频率 | 每人一段带宽,同时可以发 |
| TDM | 时间 | 每人一个时隙,轮流发 |
| CDM | 码型 | 同时同频,靠正交码区分 |
| WDM | 波长 | 光纤上按波长分(本质是光域的 FDM) |
优点:不会冲突,时延确定(适合实时业务)。缺点:频谱/时隙被"切死"——某一路没数据时,它那份资源也空着,别人用不了。
⚠️ "静态划分为什么在计算机网络里用得少":因为计算机通信是"突发性"的——一台机器可能几分钟不发一个包,然后突然发一大串。 静态划分会让"空闲用户的资源白白浪费";随机接入正是为"突发业务"设计的。
二、ALOHA:从"想说就说"到"先听再说"
纯 ALOHA 的规则只有两条:① 想发就发(不管信道忙不忙);② 一段时间收不到确认,就随机等一段时间再重发。
冲突的脆弱期(vulnerability time)= 2 个帧时:一段数据从开始发到发完需要
吞吐率公式:
其中
| 纯 ALOHA | 时隙 ALOHA | |
|---|---|---|
| 0.1 | 0.0819 | 0.0905 |
| 0.25 | 0.1516 | 0.1947 |
| 0.5 | 0.1839(纯 ALOHA 最优) | 0.3033 |
| 1.0 | 0.1353 | 0.3679(时隙 ALOHA 最优) |
| 1.5 | 0.0747 | 0.3347 |
| 2.0 | 0.0366 | 0.2707 |
⚠️ 两个"必背的极限值":
- 纯 ALOHA 的最大吞吐率 =
(在 时取得)。 - 时隙 ALOHA 的最大吞吐率 =
(在 时取得)。 "时隙 ALOHA 恰好是纯 ALOHA 的两倍"——因为"只在时隙边界发送"把脆弱期从
缩到了 ,这就是"同步"带来的全部收益。 ⚠️ 18.4% 这个数字的冲击力要记住:"想说就说"的信道,最多只有 18.4% 的时间在有效传输——这就是为什么要发明 CSMA。
时隙 ALOHA 的"时隙"怎么来:所有站用一个统一时钟同步,只允许在每个时隙的开头开始发送——时隙长度 = 一个帧的发送时间
三、CSMA:先听后说
CSMA(Carrier Sense Multiple Access,载波监听多路访问)在 ALOHA 的基础上加了"听":发送前先监听信道,只有"空闲"才发。
但"听到空闲之后怎么行动"有三种流派(必背对照):
| 策略 | 听到空闲时 | 听到忙时 | 冲突概率 | 信道利用率 | 时延 |
|---|---|---|---|---|---|
| 1-坚持 CSMA | 立刻发(概率 1) | 持续监听,一空闲就发 | 最高(多个等待者会同时发) | 较高(信道不空等) | 小 |
| 非坚持 CSMA | 立刻发 | 随机等一段时间再重新监听 | 较低(大家错开) | 较低(等待期间信道可能已空闲) | 大 |
| p-坚持 CSMA | 以概率 | 等到下一个时隙再判断 | 可调( | 可调 | 中等 |
⚠️ "1-坚持"和"非坚持"的取舍是本节最该理解的一对:
- 1-坚持的问题:"一空闲就发"会让所有等待者同时冲向信道,冲突概率最高——但优点是信道利用率高(不空等)。
- 非坚持的优点是"错开",但它"随机等一段时间"时并不知道信道是否变空闲了,可能白等——利用率反而低。
- p-坚持是两者的折中:
取 1 就退化成 1-坚持, 取小就接近非坚持——"用概率把冲突和空等都摊薄"。
⚠️ 一个容易被忽略的前置条件:CSMA 有效的前提是"传播时延远小于帧的发送时间"——因为"听到空闲"这个判断本身就有
的滞后:A 听到空闲时,B 可能刚刚开始发(信号还在路上)。 这个"滞后"就是 CSMA 冲突的根源,也是下一节 CSMA/CD 要根治的东西。
四、CSMA/CD:边发边听,冲突立即停止
CSMA/CD(Carrier Sense Multiple Access with Collision Detection)在 CSMA 上加了一条:发送过程中继续监听信道,一旦发现"收到的信号与自己发的不同"就立刻停止发送。
三个组成部分(必背):
| 名称 | 含义 |
|---|---|
| 载波监听(carrier sense) | 发送前先听,空闲才发 |
| 多点接入(multiple access) | 总线型拓扑,所有站都挂在同一根线上 |
| 冲突检测(collision detection) | 边发边听;一旦发现冲突立即停发 |
"边发边听"带来的最大好处:不用把整个帧发完才发现"撞了"——发现冲突就立即中止,节省带宽。 代价是:发送方的收发电路必须能"在发送的同时接收并比较"。
★ 争用期(冲突窗口)
问题:A 发出的信号,最坏情况下要过多久才能确定"没有别人在和我撞"?
text
设单程传播时延 = t
最坏情形: A 在 t=0 开始发; B 的信号恰好在"即将到达 A"的最后一刻发出
(B 是在 t = t 的时刻才开始发的)
t=0 A 开始发送, 信号向 B 走
t≈t B 处的信号还非常弱(B 认为信道空闲), B 也开始发送
t=2t A 才收到 B 的信号 -> 此时 A 才发现冲突
----------
★ 结论: A 必须在"发完全部数据之前"收到可能的最晚冲突信号
-> 帧的发送时间 >= 2t★ 最小帧长公式(必背):
其中
★ 锚点(本章定死):
| 标准 | 数据率 | 争用期 | 最小帧长 | 等效字节数 |
|---|---|---|---|---|
| 10BASE-T | 10 Mbps | 51.2 μs | 512 bit | 64 B |
| 100BASE-TX | 100 Mbps | 5.12 μs | 512 bit | 64 B |
| 1000BASE(半双工) | 1000 Mbps | 4.096 μs(载波延伸) | 4096 bit | 512 B |
三条推论:
- 10 Mbps 以太网的争用期 51.2 μs(单程
μs)是标准约定值——它由"最长 2500 m 电缆 + 4 个中继器的转发延迟"共同决定。 - 100BASE-TX 把争用期缩短到 5.12 μs,才保住了 64 B 的最小帧——办法是"把最大网段从 2500 m 缩到 100 m"(速率提高 10 倍,网段缩短约 25 倍,两头一乘净缩)。
- 千兆以太网若要继续用 CSMA/CD,最小帧就得是 512 B——这显然不现实(短控制帧无法发送),所以千兆以太网用"载波延伸"(把帧补齐到 512 B 再发)或直接上全双工(全双工没有冲突,不需要 CSMA/CD)。
⚠️ "最小帧 64 B"与
net/20-framing.md的衔接:上一章说"以太网帧长 64 ~ 1518 B",但没解释 64 为什么是 64——答案就在这里:。 上一章还把"数据不足 46 B 要填充"作为一条规则给出,现在这条规则的来历也清楚了: 。
冲突发生后的处理(三步):
text
① 立即停止发送数据
② 发送"人为干扰信号" (jamming signal)
★ 为什么要发干扰信号: 保证"线上所有人都知道发生了冲突"
否则远端的站可能收不到"被破坏的帧", 以为一切正常
③ 执行"截断二进制指数退避", 随机等一段时间后重试★ 截断二进制指数退避(Truncated Binary Exponential Backoff,BEB)
规则(必背):
等待时间 =
★ 退避时隙表(锚点):
| 第几次冲突 | 时隙数 | 平均等待 | 最大等待 | ||
|---|---|---|---|---|---|
| 1 | 1 | 0 ~ 1 | 2 | 25.6 μs(0.5 时隙) | 51.2 μs(1 时隙) |
| 2 | 2 | 0 ~ 3 | 4 | 76.8 μs(1.5) | 153.6 μs(3) |
| 3 | 3 | 0 ~ 7 | 8 | 179.2 μs(3.5) | 358.4 μs(7) |
| 4 | 4 | 0 ~ 15 | 16 | 384.0 μs(7.5) | 768.0 μs(15) |
| 5 | 5 | 0 ~ 31 | 32 | 793.6 μs(15.5) | 1587.2 μs(31) |
| 6 | 6 | 0 ~ 63 | 64 | 1612.8 μs(31.5) | 3225.6 μs(63) |
| 7 | 7 | 0 ~ 127 | 128 | 3251.2 μs(63.5) | 6502.4 μs(127) |
| 8 | 8 | 0 ~ 255 | 256 | 6528.0 μs(127.5) | 13056.0 μs(255) |
| 9 | 9 | 0 ~ 511 | 512 | 13081.6 μs(255.5) | 26163.2 μs(511) |
| 10 | 10 | 0 ~ 1023 | 1024 | 26188.8 μs(511.5) | 52377.6 μs(1023) |
| 11 ~ 15 | 仍为 10 | 0 ~ 1023 | 1024 | 同上("截断"就是指这里) | 同上 |
| 16 | —— | 放弃 | —— | 丢弃该帧, 报告上层 | —— |
⚠️ 两个"截断"的确切含义:
的截断:重传次数超过 10 以后, 不再增长(恒为 10)——否则 会指数爆炸(第 16 次时 个时隙 = 3.36 s,重传延迟大得离谱)。 - 次数的截断:重传 16 次仍不成功就放弃——这是"防止某个站因为持续冲突而无限占用网络",把失败上报给上层处理。
"时隙取
而不是别的值"的原因: 正好是"一个人能确定自己是否碰撞"的时间单位——等待整数个 ,等价于"大家按同一把尺子错开"。
★ 锚点(第 1 次冲突的平均等待 25.6 μs):这就是"最低限度的退避时间"——冲突次数越多,退避的期望时间越长(第 10 次已到 26188.8 μs ≈ 26.2 ms),这正是"网络越拥挤、恢复越慢"的定量表现。
五、CSMA/CA:无线为什么不能"边听边说"
无线局域网(WLAN,IEEE 802.11)用的是 CSMA/CA(Collision Avoidance,冲突避免)——"避免"而不是"检测",因为无线根本检测不了。
★ 无线不能用 CSMA/CD 的三个理由(必背):
| 理由 | 说明 |
|---|---|
| ① 无法"边发边听" | 自己发送的信号强度远大于对方到达的信号——自己的信号会把自己的接收电路"淹没",根本听不出冲突 |
| ② 隐蔽站问题(hidden station) | A 与 C 都在 B 的覆盖内,但彼此听不到——A 发时监听是"空闲"(因为听不到 C),C 也这么判断,于是"在 B 处撞车",而 A、C 都不知道 |
| ③ 暴露站问题(exposed station) | B 在发,C 听到了(以为信道忙)而不发;但 C 发的对象 D 其实离 B 很远、完全不受影响——C 白白让出信道,效率损失 |
CSMA/CA 的"四件套":
text
① ACK 确认 —— 收不到 ACK 就认为"帧丢了或撞了", 超时重发
★ 这是"没有冲突检测"的必然替代: 检测不了冲突, 只能靠"事后确认"推断
② 帧间间隔 IFS —— 用不同的等待长短表达优先级
SIFS (短) < PIFS (中) < DIFS (长)
★ 等待越短优先级越高: ACK 用 SIFS, 所以它能抢在别人之前发出
③ 随机退避 —— 信道空闲后不立即发, 而是先随机退避一段时间
★ 这是"避免"而不是"检测": 在冲突发生前就把大家错开
④ RTS/CTS 可选 —— 发送方先发 RTS, 接收方回 CTS, 其他站听到 CTS 就闭嘴
★ 这是专门为解决"隐蔽站"设计的: CTS 由接收方发出, 覆盖范围内的所有站都能听到
★ 代价: 两次短帧的额外开销, 所以只对"长帧"才用 (阈值可调)
⑤ NAV (虚拟载波监听) —— 听到 RTS/CTS 里的"还要占用多久"字段, 就地记下,
期间即使物理上听不到任何信号, 也认为信道忙★ CSMA/CD 与 CSMA/CA 的对照(必背):
| 对比项 | CSMA/CD | CSMA/CA |
|---|---|---|
| 全称后半个词 | Collision Detection(检测) | Collision Avoidance(避免) |
| 适用介质 | 有线(总线型以太网) | 无线(802.11 WLAN) |
| 冲突处理时机 | 冲突发生后立即停止 | 冲突发生前尽量错开 |
| 能否边发边听 | 能 | 不能(自己的信号淹没收信) |
| 是否有 ACK | 不需要(冲突已当场检测到) | 必须有(唯一能推断丢帧的手段) |
| 是否有退避 | 冲突后退避(二进制指数退避) | 发送前就退避(随机退避) |
| 是否有 RTS/CTS | 无 | 有(可选,解决隐蔽站) |
| 最小帧长约束 | 有( | 无此约束 |
| 为什么 | "先听后发 + 边发边听" | "先听后发 + 冲突前退避 + 事后确认" |
⚠️ 一句话记住两者的本质差别:CD 是"撞了马上停",CA 是"尽量别撞"——有线因为"能同时收自己发的信号",所以可以检测;无线因为"收不到对方的弱信号",只能避免。
⚠️ 一个极易混的点:CSMA/CA 也有"载波监听"(名字里的 Carrier Sense),它监听的既有物理载波,也有 NAV 这个"虚拟载波"——所以它其实有"两套耳朵"。
六、受控接入:轮询与令牌
| 方式 | 怎么做 | 优点 | 缺点 |
|---|---|---|---|
| 轮询(polling) | 主站依次问各从站"有没有数据要发" | 无冲突;时延有上界 | 依赖主站;主站故障全网瘫痪;轮询本身有开销 |
| 令牌环(token ring) | 一个"令牌"在环上转,拿到令牌才能发 | 无冲突;重负载时效率高 | 令牌丢失/重复要处理;环断则全网断 |
| 令牌总线(token bus) | 总线拓扑 + 令牌逻辑环 | 兼顾总线成本与令牌的无冲突 | 逻辑环维护复杂 |
⚠️ "受控接入 vs 随机接入"的选择取决于负载:轻负载时随机接入更好(不用等令牌);重负载时受控接入更好(不会冲突浪费)。 这就是"为什么令牌环在早期局域网里与以太网并存、最终又被以太网淘汰"——因为典型办公负载是突发的、轻的。
示例
例 1:C 实现——最小帧长与二进制指数退避
参数:单程传播时延
= 25.6 / 2.56 / 2.048 μs;数据率 10 / 100 / 1000 Mbps;1 时隙 = 51.2 μs(10 Mbps 下);退避次数 1 ~ 10。
#include <stdio.h>
int main(void) {
int k, i;
printf("① CSMA/CD 最小帧长 = 争用期 2t x 数据率\n");
{
double tau[3] = {25.6, 2.56, 2.048}; /* 单程传播时延, 单位 us */
double rate[3] = {10.0, 100.0, 1000.0}; /* 数据率, 单位 Mbps */
const char *nm[3] = {"10BASE-T", "100BASE-TX", "1000BASE half-duplex"};
for (i = 0; i < 3; i++) {
double slot2 = 2.0 * tau[i]; /* 争用期 us */
double bits = slot2 * rate[i]; /* us x Mbps = bit */
printf(" %-20s 2t = %7.3f us, %6.0f Mbps -> Lmin = %6.0f bit = %6.1f B\n",
nm[i], slot2, rate[i], bits, bits / 8.0);
}
printf(" 10BASE-T 的 64 B 与 net/20 的\"最小帧 64 B\"是同一个数\n");
printf(" 1000 Mbps 靠\"载波延伸\"把等效争用期提到 4096 bit = 512 B\n");
}
printf("\n② 截断二进制指数退避: k = min(重传次数, 10), r 取 [0, 2^k-1], 时隙 = 51.2 us\n");
printf(" 冲突次数 | k | r 的取值范围 | 时隙数 | 平均等待(us) | 最大等待(us)\n");
for (k = 1; k <= 10; k++) {
int slots = 1 << k; /* 2^k 个时隙 */
printf(" 第 %2d 次 | %2d | 0 ~ %4d | %4d | %10.1f | %10.1f\n",
k, k, slots - 1, slots,
(slots - 1) / 2.0 * 51.2, (slots - 1) * 51.2);
}
printf(" 第 11~15 次: k 仍为 10 (这就是\"截断\"); 第 16 次: 放弃并报告上层\n");
return 0;
}
c 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
预期输出:
① CSMA/CD 最小帧长 = 争用期 2t x 数据率
10BASE-T 2t = 51.200 us, 10 Mbps -> Lmin = 512 bit = 64.0 B
100BASE-TX 2t = 5.120 us, 100 Mbps -> Lmin = 512 bit = 64.0 B
1000BASE half-duplex 2t = 4.096 us, 1000 Mbps -> Lmin = 4096 bit = 512.0 B
10BASE-T 的 64 B 与 net/20 的"最小帧 64 B"是同一个数
1000 Mbps 靠"载波延伸"把等效争用期提到 4096 bit = 512 B
② 截断二进制指数退避: k = min(重传次数, 10), r 取 [0, 2^k-1], 时隙 = 51.2 us
冲突次数 | k | r 的取值范围 | 时隙数 | 平均等待(us) | 最大等待(us)
第 1 次 | 1 | 0 ~ 1 | 2 | 25.6 | 51.2
第 2 次 | 2 | 0 ~ 3 | 4 | 76.8 | 153.6
第 3 次 | 3 | 0 ~ 7 | 8 | 179.2 | 358.4
第 4 次 | 4 | 0 ~ 15 | 16 | 384.0 | 768.0
第 5 次 | 5 | 0 ~ 31 | 32 | 793.6 | 1587.2
第 6 次 | 6 | 0 ~ 63 | 64 | 1612.8 | 3225.6
第 7 次 | 7 | 0 ~ 127 | 128 | 3251.2 | 6502.4
第 8 次 | 8 | 0 ~ 255 | 256 | 6528.0 | 13056.0
第 9 次 | 9 | 0 ~ 511 | 512 | 13081.6 | 26163.2
第 10 次 | 10 | 0 ~ 1023 | 1024 | 26188.8 | 52377.6
第 11~15 次: k 仍为 10 (这就是"截断"); 第 16 次: 放弃并报告上层⚠️ 三点说明:
- 本机无 C 编译器:此段代码逐行人工审查,并用等价的 Python 实现实跑核对,输出 20 行逐字一致。
- 单位换算的巧合要看懂:"μs × Mbps"恰好等于 "bit"(
)——所以" (μs)× 数据率(Mbps)"就直接是最小帧长的比特数,不用再乘系数。 第 3 行的 不是"网段变长了",而是标准用"载波延伸"把等效争用期提到 4096 bit = 512 B——若只认"物理往返传播时延",千兆下它只有约 0.512 μs,那样算出的最小帧仍是 512 bit = 64 B,但要求把网段从 100 m 缩到约 10 m,工程上做不到。 %-14.1f排在最后一列:C 的printf对数字字段的宽度补空格是安全的(数字是 ASCII)——但如果哪一列要放中文,%-Ns会按字节补齐而错位(见net/20-framing.md的说明)。
例 2:Python——ALOHA 吞吐率、退避表与冲突域
import math
def pad(s, w):
"""按"显示宽度"补空格: 中文算 2 列, 否则终端里对不齐"""
return s + ' ' * max(0, w - sum(2 if ord(c) > 0x2000 else 1 for c in s))
print('=== ① 介质访问控制的两大类 ===')
print(' ' + pad('类别', 18) + pad('代表方法', 30) + '特点')
for a, b, c in [('静态划分信道', 'FDM / TDM / CDM / WDM', '不冲突, 但低负载时严重浪费'),
('随机接入', 'ALOHA / CSMA / CSMA-CD / CA', '可能冲突, 轻负载效率高'),
('受控接入', '轮询 / 令牌环 / 令牌总线', '不冲突, 时延有上界, 需控制点')]:
print(' ' + pad(a, 18) + pad(b, 30) + c)
print()
print('=== ② ALOHA 吞吐率: 纯 ALOHA 上限 18.4%, 时隙 ALOHA 上限 36.8% ===')
print(' 纯 ALOHA: S = G e^(-2G) (脆弱期 2 个帧时); 时隙 ALOHA: S = G e^(-G) (脆弱期 1 个)')
print(' ' + pad('负载 G', 10) + pad('纯 ALOHA', 14) + pad('时隙 ALOHA', 14) + '更优者')
for G in [0.1, 0.25, 0.5, 1.0, 1.5, 2.0]:
sp = G * math.exp(-2 * G)
ss = G * math.exp(-G)
print(' ' + pad('%.2f' % G, 10) + pad('%.4f' % sp, 14) + pad('%.4f' % ss, 14)
+ '时隙 ALOHA' + (' <- 纯 ALOHA 的最优点' if G == 0.5 else
(' <- 时隙 ALOHA 的最优点' if G == 1.0 else '')))
best_p = max(((g / 1000.0, (g / 1000.0) * math.exp(-2 * g / 1000.0)) for g in range(10, 3001)),
key=lambda t: t[1])
best_s = max(((g / 1000.0, (g / 1000.0) * math.exp(-g / 1000.0)) for g in range(10, 3001)),
key=lambda t: t[1])
print(' 纯 ALOHA 最大 %.4f 出现在 G = %.3f (理论值 1/(2e) = %.4f)'
% (best_p[1], best_p[0], 1 / (2 * math.e)))
print(' 时隙 ALOHA 最大 %.4f 出现在 G = %.3f (理论值 1/e = %.4f)'
% (best_s[1], best_s[0], 1 / math.e))
print(' ★ 时隙化把脆弱期从 2 个帧时缩到 1 个, 于是最优吞吐率刚好翻倍')
print()
print('=== ③ CSMA 三种坚持策略 ===')
print(' ' + pad('策略', 16) + pad('听到空闲', 24) + pad('听到忙', 26) + '冲突概率')
for a, b, c, d in [('1-坚持', '立刻发(概率 1)', '一直听, 一空就发', '最高'),
('非坚持', '立刻发', '随机等一段再重新听', '较低'),
('p-坚持', '以概率 p 发', '等到下一时隙再判断', '可调(p 越小越低)')]:
print(' ' + pad(a, 16) + pad(b, 24) + pad(c, 26) + d)
print(' ★ 1-坚持利用率高但冲突最多; 非坚持冲突少但可能白等; p-坚持是折中')
print()
print('=== ④ CSMA/CD 最小帧长 = 2t x C ===')
print(' ' + pad('标准', 26) + pad('数据率', 12) + pad('争用期 2t', 14) + pad('最小帧长', 16) + '等效字节')
for nm, tau, rate in [('10BASE-T', 25.6, 10.0), ('100BASE-TX', 2.56, 100.0),
('1000BASE half-duplex', 2.048, 1000.0)]:
s2 = 2 * tau
bits = s2 * rate
print(' ' + pad(nm, 26) + pad('%.0f Mbps' % rate, 12) + pad('%.3f us' % s2, 14)
+ pad('%.0f bit' % bits, 16) + '%.1f B' % (bits / 8))
print(' ★ 100 Mbps 把争用期缩到 5.12 us (网段 2500 m -> 100 m), 才保住 64 B')
print(' ★ 千兆半双工用载波延伸把等效争用期提到 4096 bit = 512 B')
print()
print('=== ⑤ 截断二进制指数退避 (1 时隙 = 51.2 us) ===')
print(' ' + pad('第几次冲突', 12) + pad('k', 6) + pad('r 范围', 14) + pad('时隙数', 10)
+ pad('平均等待', 16) + '最大等待')
for k in range(1, 11):
slots = 1 << k
print(' ' + pad('第 %d 次' % k, 12) + pad(str(k), 6) + pad('0 ~ %d' % (slots - 1), 14)
+ pad(str(slots), 10) + pad('%.1f us' % ((slots - 1) / 2.0 * 51.2), 16)
+ '%.1f us' % ((slots - 1) * 51.2))
print(' 第 11~15 次: k 仍为 10; 第 16 次: 放弃该帧并报告上层')
print(' ★ 第 1 次平均只等 25.6 us, 第 10 次平均要等 26188.8 us —— 越挤恢复越慢')
print()
print('=== ⑥ CSMA/CD 与 CSMA/CA 对照 ===')
print(' ' + pad('对比项', 22) + pad('CSMA/CD', 30) + 'CSMA/CA')
for a, b, c in [('后半词含义', 'Collision Detection 检测', 'Collision Avoidance 避免'),
('适用介质', '有线总线型以太网', '无线 802.11 WLAN'),
('处理时机', '冲突发生后立即停止', '冲突发生前尽量错开'),
('能否边发边听', '能', '不能(自己的信号淹没收信)'),
('是否需要 ACK', '不需要', '必须有(唯一能推断丢帧的手段)'),
('退避时机', '冲突后退避', '发送前就退避'),
('RTS/CTS', '无', '有(可选, 解决隐蔽站)'),
('最小帧长约束', '有 (2t x C)', '无此约束')]:
print(' ' + pad(a, 22) + pad(b, 30) + c)
print()
print('=== ⑦ 冲突域与广播域 (设备归属判据: 这个设备看得懂哪种地址) ===')
print(' ' + pad('设备', 12) + pad('工作层', 12) + pad('隔离冲突域', 18) + '隔离广播域')
for a, b, c, d in [('集线器', '物理层', '不能', '不能'),
('交换机', '链路层', '能(每端口一个)', '不能(除非划 VLAN)'),
('路由器', '网络层', '能', '能')]:
print(' ' + pad(a, 12) + pad(b, 12) + pad(c, 18) + d)
print(' 例: 1 台交换机 3 个端口各接 1 台集线器, 每台集线器接 4 台主机')
print(' 冲突域 = 3 个(每台集线器算 1 个), 广播域 = 1 个, 主机数 = 12')
print(' ★ 集线器内部是"一个冲突域"; 交换机每个端口各是一个冲突域')
python 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
输出对照(真实运行结果):
=== ① 介质访问控制的两大类 ===
类别 代表方法 特点
静态划分信道 FDM / TDM / CDM / WDM 不冲突, 但低负载时严重浪费
随机接入 ALOHA / CSMA / CSMA-CD / CA 可能冲突, 轻负载效率高
受控接入 轮询 / 令牌环 / 令牌总线 不冲突, 时延有上界, 需控制点
=== ② ALOHA 吞吐率: 纯 ALOHA 上限 18.4%, 时隙 ALOHA 上限 36.8% ===
纯 ALOHA: S = G e^(-2G) (脆弱期 2 个帧时); 时隙 ALOHA: S = G e^(-G) (脆弱期 1 个)
负载 G 纯 ALOHA 时隙 ALOHA 更优者
0.10 0.0819 0.0905 时隙 ALOHA
0.25 0.1516 0.1947 时隙 ALOHA
0.50 0.1839 0.3033 时隙 ALOHA <- 纯 ALOHA 的最优点
1.00 0.1353 0.3679 时隙 ALOHA <- 时隙 ALOHA 的最优点
1.50 0.0747 0.3347 时隙 ALOHA
2.00 0.0366 0.2707 时隙 ALOHA
纯 ALOHA 最大 0.1839 出现在 G = 0.500 (理论值 1/(2e) = 0.1839)
时隙 ALOHA 最大 0.3679 出现在 G = 1.000 (理论值 1/e = 0.3679)
★ 时隙化把脆弱期从 2 个帧时缩到 1 个, 于是最优吞吐率刚好翻倍
=== ③ CSMA 三种坚持策略 ===
策略 听到空闲 听到忙 冲突概率
1-坚持 立刻发(概率 1) 一直听, 一空就发 最高
非坚持 立刻发 随机等一段再重新听 较低
p-坚持 以概率 p 发 等到下一时隙再判断 可调(p 越小越低)
★ 1-坚持利用率高但冲突最多; 非坚持冲突少但可能白等; p-坚持是折中
=== ④ CSMA/CD 最小帧长 = 2t x C ===
标准 数据率 争用期 2t 最小帧长 等效字节
10BASE-T 10 Mbps 51.200 us 512 bit 64.0 B
100BASE-TX 100 Mbps 5.120 us 512 bit 64.0 B
1000BASE half-duplex 1000 Mbps 4.096 us 4096 bit 512.0 B
★ 100 Mbps 把争用期缩到 5.12 us (网段 2500 m -> 100 m), 才保住 64 B
★ 千兆半双工用载波延伸把等效争用期提到 4096 bit = 512 B
=== ⑤ 截断二进制指数退避 (1 时隙 = 51.2 us) ===
第几次冲突 k r 范围 时隙数 平均等待 最大等待
第 1 次 1 0 ~ 1 2 25.6 us 51.2 us
第 2 次 2 0 ~ 3 4 76.8 us 153.6 us
第 3 次 3 0 ~ 7 8 179.2 us 358.4 us
第 4 次 4 0 ~ 15 16 384.0 us 768.0 us
第 5 次 5 0 ~ 31 32 793.6 us 1587.2 us
第 6 次 6 0 ~ 63 64 1612.8 us 3225.6 us
第 7 次 7 0 ~ 127 128 3251.2 us 6502.4 us
第 8 次 8 0 ~ 255 256 6528.0 us 13056.0 us
第 9 次 9 0 ~ 511 512 13081.6 us 26163.2 us
第 10 次 10 0 ~ 1023 1024 26188.8 us 52377.6 us
第 11~15 次: k 仍为 10; 第 16 次: 放弃该帧并报告上层
★ 第 1 次平均只等 25.6 us, 第 10 次平均要等 26188.8 us —— 越挤恢复越慢
=== ⑥ CSMA/CD 与 CSMA/CA 对照 ===
对比项 CSMA/CD CSMA/CA
后半词含义 Collision Detection 检测 Collision Avoidance 避免
适用介质 有线总线型以太网 无线 802.11 WLAN
处理时机 冲突发生后立即停止 冲突发生前尽量错开
能否边发边听 能 不能(自己的信号淹没收信)
是否需要 ACK 不需要 必须有(唯一能推断丢帧的手段)
退避时机 冲突后退避 发送前就退避
RTS/CTS 无 有(可选, 解决隐蔽站)
最小帧长约束 有 (2t x C) 无此约束
=== ⑦ 冲突域与广播域 (设备归属判据: 这个设备看得懂哪种地址) ===
设备 工作层 隔离冲突域 隔离广播域
集线器 物理层 不能 不能
交换机 链路层 能(每端口一个) 不能(除非划 VLAN)
路由器 网络层 能 能
例: 1 台交换机 3 个端口各接 1 台集线器, 每台集线器接 4 台主机
冲突域 = 3 个(每台集线器算 1 个), 广播域 = 1 个, 主机数 = 12
★ 集线器内部是"一个冲突域"; 交换机每个端口各是一个冲突域七条结论:
- 两大类方法的选择取决于负载:静态划分不冲突但低负载浪费;随机接入轻负载高效但会冲突——计算机通信是突发的,所以局域网一律选随机接入。
- ★ ALOHA 的两个上限:纯 ALOHA 最大吞吐率
( );时隙 ALOHA ( )——"时隙化把脆弱期从 2 个帧时缩到 1 个,上限刚好翻倍"。 - CSMA 的三种坚持各有取舍:1-坚持冲突最多但利用率高;非坚持冲突少但可能白等;p-坚持用概率折中。
- ★ 最小帧长锚点:10BASE-T 的
、10 Mbps → 512 bit = 64 B;100BASE-TX 用 保住 64 B;千兆半双工靠载波延伸把等效争用期提到 4096 bit = 512 B。 - ★ 退避锚点:第 1 次冲突平均等 25.6 μs(0.5 时隙),第 10 次平均等 26188.8 μs(511.5 时隙)——相差 1023 倍,"越拥挤恢复越慢"。
- CSMA/CA 用"四件套"替代"冲突检测":ACK(推断丢帧)+ IFS(优先级)+ 随机退避(提前错开)+ RTS/CTS(解决隐蔽站)——因为无线"边发边听"根本做不到。
- 冲突域与广播域看设备懂哪种地址:集线器(物理层)都不能隔离;交换机(链路层)隔离冲突域不隔离广播域;路由器(网络层)两者都隔离——锚点例:1 台交换机 + 3 台集线器 + 12 台主机 → 冲突域 3 个、广播域 1 个。
考点
考点
1. 必背结论
- 介质访问控制的两大类:静态划分信道(FDM/TDM/CDM/WDM)与动态接入(随机接入 + 受控接入)。
- 随机接入四兄弟:ALOHA → 时隙 ALOHA → CSMA → CSMA/CD(有线)/ CSMA/CA(无线)。
- ★ ALOHA 两个上限:纯 ALOHA
( );时隙 ALOHA ( )。 - 纯 ALOHA 的脆弱期是 2 个帧时,时隙 ALOHA 是 1 个——这是两者吞吐率差一倍的原因。
- CSMA 三种坚持:1-坚持(冲突最多、利用率高)/ 非坚持(冲突少、可能白等)/ p-坚持(折中,
可调)。 - CSMA/CD 的三要素:载波监听 + 多点接入 + 冲突检测。
- ★ 争用期:
(最坏情况下"确定没撞"要等的时间)= 往返传播时延。 - ★ 最小帧长:
——"帧的发送时间必须 争用期"。 - ★ 锚点:10BASE-T:
、10 Mbps → 512 bit = 64 B;100BASE-TX: → 仍是 64 B;1000BASE 半双工:载波延伸至 4096 bit = 512 B。 - 冲突后的三步:立即停发 → 发人为干扰信号(jamming)→ 二进制指数退避。
- ★ 为什么发人为干扰信号:保证线上所有站都能感知到冲突(否则远端站可能误以为收到了完好的帧)。
- ★ 截断二进制指数退避:
; 在 中随机取;等待 个时隙(1 时隙 = = 51.2 μs);重传 16 次后放弃。 - ★ 退避锚点:第 1 次平均 0.5 时隙 = 25.6 μs、最大 1 时隙 = 51.2 μs;第 10 次平均 511.5 时隙 = 26188.8 μs、最大 1023 时隙 = 52377.6 μs。
- "截断"的两重含义:
超过 10 不再增长;重传超过 16 次放弃。 - ★ 无线不能用 CSMA/CD 的三个理由:无法边发边听(自己的信号淹没收信)/ 隐蔽站问题 / 暴露站问题。
- CSMA/CA 的四件套:ACK 确认 / 帧间间隔 IFS(SIFS < PIFS < DIFS)/ 随机退避 / RTS-CTS(可选);另有 NAV 虚拟载波监听。
- 受控接入:轮询 / 令牌环 / 令牌总线——无冲突、时延有界,但依赖控制点。
- 冲突域/广播域的判据:看设备"看得懂哪种地址"——集线器(物理层)都不隔离;交换机(链路层)隔离冲突域不隔离广播域;路由器(网络层)都隔离。
2. 高频陷阱
- 纯 ALOHA 的上限记成 36.8%:错。纯 ALOHA 是 18.4%(
),时隙 ALOHA 才是 36.8%( )。 - 认为"时隙 ALOHA 与纯 ALOHA 的差别只是同步":不完整。关键差别是"脆弱期从 2 个帧时缩到 1 个"——同步只是手段,脆弱期减半才是吞吐率翻倍的原因。
- 最小帧长公式写成
:错。是 ——要"往返"才知道有没有冲突,漏掉 2 会算成 32 B。 - 把争用期说成"单程传播时延":错。争用期 = 往返传播时延
= 51.2 μs(10 Mbps),单程是 25.6 μs。 - 把 51.2 μs 当"帧的发送时间":错。它是争用期(往返传播时延);"最小帧 64 B 的发送时间"恰好也等于 51.2 μs——两者数值相同但物理含义不同,这是本题最妙的巧合。
- 认为"100 Mbps 以太网的最小帧变大了":错。仍是 64 B——办法是缩短网段(2500 m → 100 m)把争用期压到 5.12 μs。
- 认为"千兆以太网没有 CSMA/CD":不准确。半双工千兆仍用 CSMA/CD,但需要"载波延伸"(帧补到 512 B);全双工模式才不需要 CSMA/CD。
- 二进制指数退避里
无上限地增长:错。 ,超过 10 就不再增长——这是"截断"的含义之一。 - 退避时隙写成"
":错。是 (1 个时隙 = 一个争用期 = 51.2 μs)。 - 认为"冲突后可以立即重发":错。必须等"人为干扰信号"发完 + 随机退避——立即重发会与对方再次相撞。
- 把 CSMA/CA 的 A 理解成 "ACK":错。CA = Collision Avoidance(冲突避免)——虽然它确实需要 ACK,但名字的来源不是 ACK。
- 认为"CSMA/CA 也做冲突检测":错。它检测不了(自己的信号淹没收信),只能"避免 + 事后确认"。
- 把"隐蔽站"与"暴露站"说反:隐蔽站 = 双方都听不到对方却在中间站相撞(该避免却不知道);暴露站 = 明明不会撞却白白让出信道(不该让却让了)。
- 认为"交换机隔离广播域":错。交换机只隔离冲突域;隔离广播域要靠路由器或 VLAN。
- 认为"集线器的每个端口是一个冲突域":错。集线器工作在物理层,整台设备(所有端口)同属一个冲突域。
3. 解题模板("介质访问控制计算题")
① 先辨场景: 有线(总线以太网) -> CSMA/CD; 无线(WLAN) -> CSMA/CA
② 最小帧长: Lmin = 2t x C
给"网段长度 L、传播速率 v" -> t = L / v, 2t = 2L / v
给"数据率 C" -> Lmin(bit) = 2t(us) x C(Mbps)
锚点: 51.2 us x 10 Mbps = 512 bit = 64 B
反求: 若最小帧已知, 可反推最大网段 -> 这是"为什么 100 Mbps 网段只有 100 m"
③ ALOHA 吞吐: 纯 S = G e^(-2G) 上限 18.4%; 时隙 S = G e^(-G) 上限 36.8%
④ 退避题: k = min(次数, 10)
r 取 [0, 2^k - 1]; 平均 = (2^k - 1)/2 个时隙; 最大 = (2^k - 1) 个时隙
1 个时隙 = 2t = 51.2 us(10 Mbps)
⑤ 冲突域/广播域: 问一句"这个设备看得懂哪种地址"
集线器 -> 不隔离任何域; 交换机 -> 隔离冲突域; 路由器 -> 都隔离
计数法: 每个交换机的端口 = 1 个冲突域; 每台集线器整机 = 1 个冲突域
⑥ 判断题出现"无线"就先想: 边发边听做不到 -> 必然有 ACK + 退避4. 与相邻章节的接口
net/20-framing.md(封装成帧):"以太网最小帧 64 B"与"数据不足 46 B 要填充"整条结论在本章被推导出来——上一章只给了数,本章给了理由。net/22-window.md(滑动窗口):上一章的"超时重传 + 序号"解决"帧丢了";本章解决"帧撞了"——两者的共同点是"都要随机化重试时机以免再次冲突"(一个靠超时定时器,一个靠二进制指数退避)。net/24-ethernet.md(以太网):下一章是本章的"工程落地版"——帧格式、MAC 地址、交换机自学习、冲突域计数都在那一章展开;本章的"64 B 最小帧"到那里变成"帧长合法性检查"。net/10-physical.md(物理层):"10BASE-T 用曼彻斯特编码、需 20 MHz 带宽"是上一章的结论;本章的"10 Mbps / 100 m / 双绞线"与它是同一套工程参数。net/44-congestion.md(TCP 拥塞控制):"网络拥挤时退避"这件事在链路层靠二进制指数退避,在传输层靠慢开始与拥塞窗口——两层在做同一件事:把"过载"变成"降速"。os/12-sync.md(同步与互斥):"多个站抢一条信道"与"多个进程抢一个临界资源"是同一个问题——CSMA 的"先听后发"对应"进入区检查","退避"对应"等待后重试","冲突检测"对应"发现并回滚"。os/11-scheduling.md(处理机调度):"1-坚持/非坚持/p-坚持"与"抢占/非抢占/时间片"是同一类策略取舍——都在"利用率"与"公平/冲突"之间做权衡。
小结
- 介质访问控制 = 共享信道的发言规则;两大类:静态划分信道与动态接入(随机接入 + 受控接入)。
- ★ ALOHA 上限:纯 ALOHA 18.4%(
, );时隙 ALOHA 36.8%( , )——差在脆弱期是 2 个还是 1 个帧时。 - CSMA 三种坚持:1-坚持(冲突多、效率高)/ 非坚持(冲突少、可能白等)/ p-坚持(折中)。
- CSMA/CD 三要素:载波监听 + 多点接入 + 冲突检测;冲突后:立即停发 → 发干扰信号 → 二进制指数退避。
- ★ 最小帧长:
;锚点: 、10 Mbps → 512 bit = 64 B;100 Mbps 靠缩短网段(2500 m → 100 m)保住 64 B;千兆半双工用载波延伸到 4096 bit = 512 B。 - ★ 截断二进制指数退避:
、 、等待 个时隙(51.2 μs)、16 次后放弃;第 1 次平均 25.6 μs,第 10 次平均 26188.8 μs。 - ★ 无线不用 CSMA/CD 的三个理由:边发边听做不到 / 隐蔽站 / 暴露站;CSMA/CA 用 ACK + IFS + 随机退避 + RTS-CTS(+ NAV)代替冲突检测。
- 受控接入:轮询 / 令牌环 / 令牌总线——不冲突但依赖控制点。
- 冲突域/广播域:集线器都不隔离;交换机隔离冲突域;路由器两者都隔离(锚点例:3 台集线器接 1 台交换机 → 冲突域 3、广播域 1)。
下一篇:以太网与交换机
评论(0)
当前浏览器不允许本地存储,评论无法保存。
还没有评论,来说两句。