4. 隐藏节点与暴露节点:CSMA/CA机制下的经典问题
CSMA/CA 听起来很完美,对吧?先听后说,有空再发。但在真实的 WiFi 环境里,这个机制有两个天生的漏洞——隐藏节点和暴露节点。我当年第一次在产线上遇到配网失败率飙升,查了三天都没头绪,最后发现就是隐藏节点在捣鬼。
说白了,这两个问题都源于一个事实:WiFi 节点只能听到部分邻居。你以为是“大家都在听”,实际上很多人根本听不到对方。
4.1 隐藏节点:你听不到我,但我能干扰你
先看最常见的场景。假设有三个节点:A、B、C。A 和 C 都能听到 B,但 A 和 C 互相听不到。这就是典型的隐藏节点拓扑。
现在 A 要给 B 发数据。A 先侦听信道——空闲,于是开始发送。但 C 听不到 A,它以为信道也是空闲的。如果 C 也在同一时刻给 B 发数据,冲突就发生在 B 身上。B 同时收到两路信号,全都解不出来。
这就是隐藏节点问题的本质:冲突发生在接收端,但发送端感知不到。
4.2 暴露节点:我能听到你,但我其实可以发
隐藏节点的反面是暴露节点。还是三个节点:A、B、C、D。这次 A 和 B 在通信,C 在 B 的范围内,但 C 想给 D 发数据。
C 听到 B 在发数据,于是乖乖退避。但仔细想想:C 要发给 D,而 D 根本不在 B 的通信范围内。A 和 B 的通信不会干扰 C→D 的传输。C 完全可以在同一时间发送,但它被 CSMA/CA 的“听到即忙”规则给限制了。
暴露节点问题不直接导致丢包,但它严重降低信道利用率。在密集部署的场景下,这个问题会让整体吞吐量打折扣。
4.3 两种问题的对比
| 对比维度 | 隐藏节点 | 暴露节点 |
|---|---|---|
| 问题本质 | 发送端听不到对方,导致接收端冲突 | 发送端听到对方,但实际不会冲突 |
| 影响 | 丢包率上升,重传增加 | 信道利用率下降,吞吐量受限 |
| 典型场景 | 多设备同时配网、Mesh 回传链路 | 高密度 AP、相邻 BSS 重叠覆盖 |
| CSMA/CA 应对 | RTS/CTS 机制(后面详讲) | 无直接机制,依赖调度优化 |
| 配网广播影响 | 严重,直接导致配网失败 | 中等,延长配网时间 |
4.4 RTS/CTS:隐藏节点的“官方解药”
为了解决隐藏节点问题,802.11 引入了 RTS/CTS 机制。全称是 Request to Send / Clear to Send。说白了就是:发之前先问一下,确认没人用再发。
流程是这样的:
- A 发 RTS:告诉 B “我想发数据,给我 100 微秒的时间”
- B 回 CTS:告诉所有人 “A 要发数据,你们都别动”
- A 发数据:确认信道已预留,开始传输
- B 回 ACK:确认收到
关键点在于:CTS 是 B 广播的,C 能听到 B 的 CTS。所以即使 C 听不到 A 的 RTS,它也能通过 CTS 知道信道被占用了。这就绕过了隐藏节点的问题。
但 RTS/CTS 不是免费的。每次传输都要多花两个帧的开销。对于大数据包,这个开销值得;对于小数据包,反而得不偿失。
4.5 配网广播中的特殊问题
配网场景有个特殊性:广播帧不用 RTS/CTS。为什么?因为广播没有唯一的接收端,CTS 不知道该发给谁。你想想看,AP 发一个广播,总不能等所有设备都回 CTS 吧?那信道就彻底废了。
这就导致了一个尴尬的局面:配网广播帧在隐藏节点环境下是裸奔的。没有 RTS/CTS 的保护,冲突概率直线上升。
4.6 工程中的应对策略
既然 RTS/CTS 对广播无效,我们怎么在工程层面减少隐藏节点的影响?我总结了几个实战经验:
- 错峰发送:配网 App 加入随机延迟,避免多设备同时发送广播。延迟范围建议 500ms-2s。
- 增加重传次数:广播帧默认重传次数通常为 1-2 次。在配网场景下,建议提高到 3-5 次。
- 降低发送速率:低速率(如 1Mbps)的覆盖范围更大,能减少隐藏节点的“盲区”。
- 信道选择:如果 AP 支持,选择干扰较少的信道。可以用 Wi-Fi Analyzer 之类的工具扫一下。
- ACK 确认变通:虽然广播没有 ACK,但可以让设备在收到广播后单独发一个 Unicast ACK 给 AP,AP 据此判断广播是否成功。
4.7 小结
隐藏节点和暴露节点,是 CSMA/CA 机制下的一体两面。一个导致丢包,一个浪费信道。在配网广播这个特殊场景里,隐藏节点问题尤其突出——因为广播帧没有 RTS/CTS 的保护。
理解这两个问题,不是为了背概念。而是当你下次看到配网失败率异常时,能多一个排查方向:是不是有隐藏节点?要不要错开发送时间?能不能调整重传策略?
嗯,这些实战经验,比单纯记住定义有用得多。