RTS/CTS 是 802.11 里很常见的保护机制。很多资料会把它讲成“发送数据前先握手”,这个说法没错,但是排查问题时不够用。

我理解 RTS/CTS 时,更愿意把它看成一个“预约空口时间”的过程:先用很短的控制帧告诉周围设备,后面这段时间我要完成一次数据交换,你们先不要抢信道。

这篇文章按抓包分析的方式整理,不单独背字段,而是重点看这些问题:

  1. 普通 RTS 里 RA、TA 分别代表什么;
  2. Duration 到底保护了多长时间;
  3. RTS/CTS 和 CTS-to-self 有什么区别;
  4. ERP Protection 为什么会让 2.4 GHz 网络变慢;
  5. VHT/HE dynamic bandwidth RTS 为什么可能出现“看起来像组播地址”的 TA;
  6. 现场抓包时应该按什么步骤判断。

先把结论写在前面:普通 RTS 里,TA 通常就是发送方 MAC;但在 VHT/HE dynamic bandwidth RTS 里,TA 可能是 bandwidth signaling TA,不能直接按普通源地址理解。

一、RTS/CTS 解决的是什么问题

802.11 是共享介质。一个 STA 要发送数据,不能只看自己这里信道是不是空闲,还要考虑接收方附近有没有别的设备正在发。

典型隐藏节点场景如下:

protocol trace
STA A 能听到 AP
STA C 能听到 AP
STA A 和 STA C 互相听不到

这时 A 和 C 都觉得信道空闲,同时向 AP 发数据。对 AP 来说,两路信号叠在一起,数据帧就可能解不出来。

RTS/CTS 的基本流程如下:

protocol trace
STA A  -> AP      RTS
AP     -> STA A   CTS
STA A  -> AP      DATA
AP     -> STA A   ACK

这里真正有用的不只是 RTS,而是 AP 回出来的 CTS。A 附近的隐藏节点未必听得到 A 发出的 RTS,但是只要它能听到 AP 发出的 CTS,就会根据 CTS 里的 Duration 设置 NAV,在预约时间内暂停竞争。

所以 RTS/CTS 不是提高 PHY rate 的机制,它的作用是用额外控制帧开销,换取后续长数据帧少被撞掉。

二、普通 RTS 帧格式

RTS 是 control frame,格式很短:

protocol trace
Frame Control
Duration
RA
TA
FCS

普通 RTS 可以这样理解:

protocol trace
RA = Receiver Address    = RTS 接收方 = 后续 DATA 接收方
TA = Transmitter Address = RTS 发送方 = 后续 DATA 发送方

例如一个 STA 准备给 AP 发数据:

protocol trace
RTS.RA = AP  MAC
RTS.TA = STA MAC

CTS 更短,只有一个地址字段:

protocol trace
Frame Control
Duration
RA
FCS

在普通 RTS/CTS 交换里,CTS 的 RA 应该等于前一个 RTS 的 TA:

protocol trace
RTS.TA == CTS.RA

这个关系在排查普通 RTS/CTS 时很好用。但是注意,它只适用于普通场景。后面会讲到 VHT/HE dynamic bandwidth RTS,这种情况下 TA 可能不是普通发送方 MAC。

三、Duration 保护的是一段时间

RTS/CTS 的核心不是地址,而是 Duration/NAV。

经典单帧交换如下:

protocol trace
RTS -> SIFS -> CTS -> SIFS -> DATA -> SIFS -> ACK

RTS 发出去之后,后面还要留出 CTS、DATA、ACK 和 3 个 SIFS 的时间,所以常见计算方式是:

protocol trace
RTS Duration = 3*SIFS + T_CTS + T_DATA + T_ACK

CTS 里的 Duration 是剩余时间,可以近似理解为:

protocol trace
CTS Duration = RTS Duration - T_CTS - SIFS

这两个公式只适合最经典的单帧、有 ACK 的交换。如果是下面这些情况,就不能照抄:

  1. A-MPDU + Block ACK;
  2. TXOP 内连续发送多帧;
  3. No Ack policy;
  4. 分片;
  5. 管理帧响应;
  6. 宽带宽 duplicate RTS/CTS;
  7. 后续 PPDU 时长和普通 DATA/ACK 不一致。

抓包时我一般不只看字段值,还会看后续行为是否对得上:

protocol trace
RTS Duration 太短  -> 旁听 STA 可能提前竞争,DATA/ACK 被打断
RTS Duration 太长  -> 其他 STA 沉默过久,airtime 被浪费
Duration 与后续帧不匹配 -> RTS/CTS 有,但 DATA/ACK 异常或 retry 增多

也就是说,看到 RTS/CTS 不代表保护一定成功,还要看后面的 DATA、ACK、Retry、ACK miss 有没有按预期变化。

四、RTS/CTS 和 CTS-to-self 不一样

CTS-to-self 经常和 RTS/CTS 放在一起讲,但两者的保护范围不一样。

CTS-to-self 是发送方自己发一个 CTS,RA 设置成自己的地址:

protocol trace
发送方 -> 周围 STA   CTS-to-self
发送方 -> 接收方     DATA
接收方 -> 发送方     ACK

这样做的好处是开销小,因为省掉了 RTS 和接收方回复 CTS 的过程。它常见于 ERP、HT、VHT 等保护场景。

但是 CTS-to-self 只能影响听得到发送方的设备。如果问题出在接收方附近的隐藏节点,CTS-to-self 不一定能保护住。

RTS/CTS 的区别在于,CTS 是接收方发出来的:

protocol trace
发送方 -> 接收方     RTS
接收方 -> 发送方     CTS
发送方 -> 接收方     DATA
接收方 -> 发送方     ACK

接收方附近的隐藏节点更容易听到这个 CTS,从而设置 NAV。

所以不能简单说“CTS-to-self 是 RTS/CTS 的轻量版”。更准确的说法是:CTS-to-self 开销小,但保护范围偏发送方;RTS/CTS 开销更大,但更容易覆盖接收方附近的隐藏节点。

五、开启 RTS/CTS 不一定提升吞吐

RTS/CTS 是成本和收益的交换。

比较可能有收益的场景:

  1. hidden node 明显;
  2. 帧比较大,重传代价高;
  3. 链路距离远,ACK miss 或 retry 明显;
  4. mesh、无线桥接、多 AP 重叠环境复杂;
  5. RTS threshold 只对大帧启用保护。

比较容易变差的场景:

  1. 小包很多;
  2. hidden node 不明显;
  3. basic rate 很低;
  4. RTS threshold 设置太低;
  5. 2.4 GHz mixed mode 下保护帧太多。

我一般会同时看下面几组数据:

protocol trace
retry / ACK miss 有没有下降
RTS/CTS airtime 占比有没有过高
端到端吞吐有没有提升
时延和抖动有没有改善

如果只看到“RTS/CTS 开了”,但 retry 没下降、airtime 还被控制帧吃掉很多,那实际体验可能会更差。

六、ERP Protection 里的 RTS/CTS

2.4 GHz 802.11g/ERP 和 802.11b 共存时,AP 可能启用 ERP Protection。

原因是 legacy 802.11b 设备可能不能正确解码 ERP-OFDM 帧,也就拿不到这些帧里的 Duration/NAV。为了避免 legacy 设备打断 OFDM 数据帧,AP 或 STA 会先发 legacy 设备能理解的保护帧。

常见保护方式有两种:

protocol trace
RTS/CTS
CTS-to-self

排查 2.4 GHz 网络突然变慢时,不要只盯着 DATA rate。Beacon 或 Probe Response 里的 ERP Information 很关键:

protocol trace
NonERP_Present = 1  表示 BSS 或邻近环境里存在 non-ERP 影响
Use_Protection = 1 表示 ERP STA 需要使用保护机制

如果抓包里看到大量低速率 RTS/CTS 或 CTS-to-self,就要单独算 protection airtime。用户看到的现象可能是“协商速率看起来不低,但实际吞吐很差”。

七、最容易踩坑的是 bandwidth signaling TA

普通 RTS 里:

protocol trace
TA = 发送方 MAC

这句话大多数时候没问题,但不能无条件套到 VHT/HE dynamic bandwidth operation。

在 VHT/HE dynamic bandwidth 场景下,RTS 可能使用 non-HT PPDU 或 non-HT duplicate PPDU 承载。MAC 帧格式看起来仍然是普通 RTS:

protocol trace
Frame Control
Duration
RA
TA
FCS

但是这里的 TA 可能被设置成 bandwidth signaling TA。

也就是说,这个地址不一定是普通意义上的发送方原始 MAC,而是借用 RTS 的 TA 字段传递带宽相关信息。抓包里就可能看到一个“像组播地址”的 TA。

现场判断时,如果看到下面这些现象,要先停一下,不要直接判驱动填错源 MAC:

protocol trace
RTS.TA 的 Individual/Group bit 被置 1
RTS 使用 non-HT PPDU 或 non-HT duplicate PPDU
场景涉及 VHT/HE dynamic bandwidth
后续 DATA 带宽行为和请求带宽有关

另外,non-HT PPDU 的 scrambler initialization 里也可能带和带宽相关的 TXVECTOR 信息,例如:

protocol trace
CH_BANDWIDTH_IN_NON_HT
DYN_BANDWIDTH_IN_NON_HT

这些信息不在普通 MAC 字段里。不同网卡、驱动、radiotap 暴露能力不一样,Wireshark 里也不一定都能直接看到。

所以更稳的判断方式是:看到 RTS.TA 像组播地址时,先确认 PPDU 类型、是否 VHT/HE dynamic bandwidth、抓包设备覆盖的信道宽度,再看后续 DATA 是否按被确认的带宽发送。

八、Dynamic 和 Static bandwidth 的 CTS 含义

40/80/160 MHz 是由多个 20 MHz 子信道组合出来的。non-HT duplicate RTS/CTS 会在多个 20 MHz 子信道上复制 legacy 可解码的控制帧。

这里要分 dynamic bandwidth 和 static bandwidth。

Dynamic bandwidth 下,发送方可以请求较宽带宽,接收方根据各个 20 MHz 子信道的 CCA/NAV 状态,只确认可用的部分。

例如:

protocol trace
发送方请求 80 MHz
接收方只在 primary 20 MHz 回 CTS

这不一定是错误。它可能表示只有 primary 20 MHz 可用。后续合理行为是降到 20 MHz 发,或者放弃本次发送、重新竞争。

真正不合理的是:

protocol trace
CTS 只确认了 20 MHz
发送方继续按完整 80 MHz 发 DATA

这样 secondary channel 上的 STA 可能没有被 CTS/NAV 压住,后续宽带宽 DATA 就可能和 OBSS 或其他 STA 冲突。

Static bandwidth 更严格。发送方请求 80 MHz static 时,本次受保护发送通常要求完整 80 MHz 条件满足。如果只监听 primary 20 MHz,看到 RTS -> CTS,不能证明完整 80 MHz 保护成功。

CTS 后没有 DATA,也不一定是“AP 没收到 CTS”。可能原因包括:

  1. secondary 20 MHz 没有对应 duplicate CTS;
  2. secondary channel CCA busy;
  3. secondary channel 已有 NAV;
  4. 发送方没有收到满足 static 带宽要求的有效 CTS;
  5. 抓包设备没有覆盖实际 DATA 所在的带宽。

九、我会这样分析一段异常抓包

如果现场给我一段抓包,说“RTS/CTS 后面不对”,我会按下面顺序看。

第一步,先确认保护类型:

protocol trace
ordinary RTS/CTS
CTS-to-self
ERP protection
VHT/HE dynamic bandwidth RTS
static duplicate RTS

类型没定之前,不要急着解释 RA、TA、Duration。

第二步,看地址关系:

protocol trace
普通 RTS:
RTS.RA  -> 后续 DATA 接收方
RTS.TA  -> 后续 DATA 发送方
CTS.RA  -> 前一个 RTS.TA

如果 RTS.TA 看起来像组播地址,要优先检查是不是 bandwidth signaling TA。

第三步,看时序:

protocol trace
RTS -> SIFS -> CTS -> SIFS -> DATA -> SIFS -> ACK

异常一般落在这些位置:

protocol trace
RTS 后没有 CTS
CTS 不是 SIFS 后回来
CTS 后没有 DATA
DATA 后 ACK miss
Retry bit 开始堆起来

第四步,看 PHY 和带宽信息:

protocol trace
RTS/CTS rate
basic rate
PPDU 类型
channel width
primary / secondary channel
抓包设备实际覆盖了多少带宽

没有 PHY metadata 时,不要只靠 MAC header 下结论。

十、容易误判的现象

现象不能直接下的结论下一步确认
RTS.TA 像组播地址 驱动填错源 MAC 先确认是否 VHT/HE dynamic bandwidth RTS,以及是否 bandwidth signaling TA
primary 20 MHz 有 RTS/CTS 80 MHz 保护成功 还要确认 secondary 20/40/80 MHz 上的 duplicate RTS/CTS 和 CCA/NAV 条件
CTS 只在 primary 返回 接收方行为错误 dynamic bandwidth 下可能只是确认 20 MHz 可用,后续应降宽或放弃
RTS/CTS 后没有 DATA AP 一定没收到 CTS 还要查带宽语义、CCA/NAV、TX abort、抓包覆盖范围
开启 RTS/CTS 后吞吐下降 RTS/CTS 无效 可能是保护收益小于控制帧 airtime 成本
CTS-to-self 存在 等价于 RTS/CTS CTS-to-self 保护范围偏发送方,不能覆盖所有隐藏节点

十一、现场记录模板

真要把问题排清楚,建议每次把这些信息记录下来:

protocol trace
BSS / 设备:
信道 / 带宽:
primary channel:
抓包设备覆盖带宽:20 / 40 / 80 / 160 MHz
RTS 类型:ordinary / dynamic duplicate / static duplicate / CTS-to-self
RTS rate:
CTS rate:
RTS.RA:
RTS.TA:
TA I/G bit:
RTS Duration:
CTS Duration:
CTS 覆盖子信道:
后续 DATA 带宽:
DATA/ACK 是否出现:
Retry / ACK miss:
设备日志:CTS timeout / TX abort / CCA busy / NAV / rate control
结论:
还缺的证据:

十二、来源与核验

本文按公开协议语义和可抓包验证的行为整理,不把无法追溯的经验当结论。

主要参考方向:

  1. IEEE Std 802.11:RTS/CTS control frame 格式、Duration/NAV、SIFS、RTS threshold、ERP/VHT/HE 相关 MAC/PHY 语义;
  2. Wireshark / radiotap 抓包字段:RA、TA、Duration、Retry、FCS、channel、rate、channel width、PPDU/PHY metadata;
  3. 设备侧日志:CTS timeout、TX abort、CCA busy、NAV、rate control、bandwidth decision;
  4. 实验约束:只监听 primary 20 MHz 的抓包,不能代表完整 40/80/160 MHz 行为。

最后总结

普通 RTS 里,把 TA 当发送方 MAC 没问题;但是这句话必须带条件。

在 VHT/HE dynamic bandwidth RTS 中,TA 可能是 bandwidth signaling TA。抓包看到 I/G bit 置 1 或者 TA 像组播地址时,不要直接判源 MAC 错了,要结合 PPDU 类型、带宽模式和后续 DATA 行为一起看。

RTS/CTS 排障的关键不是背字段,而是先分清场景,再看地址、Duration、时序、PHY metadata 和设备日志。这样结论才不容易跑偏。