ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CSMA/CA 冲突避免机制全解析:随机退避、隐藏终端与无线调优实战

CSMA/CA 冲突避免机制全解析:随机退避、隐藏终端与无线调优实战

第一次被 CSMA/CA 这套机制“教育”,是在一栋办公楼的会议室里。几十号人开着视频会议,现场反映画面卡成幻灯片,但后台看 AP 的关联终端数并不夸张,反而信道利用率一直挂在 80% 以上,抓包一看满屏的 Retry 标志和 6Mbps 的低速率帧。那会儿我刚接手这块,第一反应是“带宽不够”,差点就去申请加 AP 了,后来顺着帧间间隔和退避窗口一层层扒下去,才发现问题出在竞争机制被少量远距离终端拖垮——这就是典型的“不是没带宽,是没人抢得到说话的机会”。CSMA/CA(Carrier Sense Multiple Access with Collision Avoidance,载波侦听多路访问/冲突避免)这个协议名字看着像教科书里的老古董,但只要你碰过无线网络、做过现场优化、或者只是好奇为什么 WiFi 上传下载不能完全对称,它就绕不过去。这篇我想把它讲透:它到底在解决什么物理层面的死结,一次成功的发送在时间轴上经历了哪些阶段,那些听起来很玄的 SIFS、DIFS、CW、NAV 到底怎么算、怎么调,以及我在实际排查里踩过的坑和一套能直接抄作业的流程。不管你是刚接触 802.11 的新手,还是已经在做无线优化的老手,希望都能拿走点东西。

1. 先搞清楚 CSMA/CA 到底在解决什么问题

1.1 有线那套“撞了再退”为什么搬不到无线

有线以太网用的是 CSMA/CD,冲突检测。它的前提很朴素:网线是共享介质,我一边发一边听,如果听到的信号和我发的不一样,说明撞车了,立刻停手、发个干扰信号、各自随机等一会儿再发。这套逻辑成立的关键是“能边发边听”。

无线做不到。射频前端是半双工的,天线在发射的瞬间,接收链路基本被自己的强信号压死,你根本听不到远处还有没有别人在发。更要命的是空间衰减:两个终端互相听不见,但都能听见 AP,这就是隐藏终端;反过来,两个终端能互相听见,但离 AP 很远,又构成了暴露终端。有线环境里“总线”是一个明确的物理范围,无线里这个“范围”是随位置、功率、遮挡动态变化的,压根就没有一条清晰的边界。

所以无线 MAC 层换了个思路:既然撞了之后没法检测,那就想办法在撞之前避开。这就是“冲突避免”四个字的由来——不是不撞,而是把撞的概率压到可接受的水平,并且用确认重传兜底。这个设计哲学上的转向,决定了后面所有的机制:帧间间隔的优先级、随机退避、RTS/CTS 握手、ACK 确认,全是为了在“没有集中调度”的前提下,让一群互不协调的设备能比较体面地共享一段频谱。

1.2 冲突避免的三板斧:先听、再等、后确认

把 CSMA/CA 拆开看,其实就三件事,顺序不能乱。

第一是载波侦听。发之前先听信道。这个“听”分两层:物理层侦听(PHY carrier sense),就是射频电路测能量,超过阈值就认为忙;以及虚拟层侦听(virtual carrier sense),靠帧头里的 Duration 字段告诉周围“我要占用多久”,其他人把这个时间写进自己的 NAV 计时器,到点之前免打扰。物理侦听能发现正在发的信号,但发现不了“即将要发”的,虚拟侦听正好补上这个空档。

第二是随机退避。信道一空闲,不是所有人一拥而上,而是各自抽一个随机数,倒计时到 0 才能发。信道忙的时候计时暂停,空闲了继续倒。这一步是整个机制的灵魂——它把“同时抢”变成了“错峰抢”,把确定性碰撞改造成了概率性错峰。

第三是确认与重传。接收方收到帧后必须回一个 ACK,发方在超时时间内没等到 ACK,就认为丢了,扩大竞争窗口重新来过。这一条保证了上层看到的是一条“看起来可靠”的链路,虽然底下全是不可靠的尽力而为。

这三件事串起来,才构成了一个完整的分布式接入控制。缺任何一个都不成立:只听不退避,大家一起等信道空闲然后一起撞;只退避不听,退避完了信道可能早被别人占了;只听退避不确认,丢包了没人知道。

1.3 两张网的技术取向对照

很多讲无线的资料喜欢一笔带过 CSMA/CD 和 CSMA/CA 的区别,但实际调优的时候,这些差异直接决定了你该关注哪些指标。我整理了一张表,是我自己在带新人时常用的对照:

维度CSMA/CD(有线共享式以太网)CSMA/CA(802.11 无线)
冲突处理时机冲突发生后检测并中止冲突发生前尽量规避
能否边发边听可以基本不行,半双工射频
冲突判断依据物理信号比对收不到 ACK 即视为失败
退避触发点检测到冲突后发送前就要退避,失败后再退避
隐藏终端概念上不存在核心难题,需要 RTS/CTS 缓解
附加开销帧间隔很小前导码、帧间间隔、ACK、退避都算开销
可靠性来源上层协议(如 TCP)MAC 层本地重传 + 上层协议

这张表里最值得盯的是最后那个“附加开销”。有线以太网一个 1500 字节的帧,帧间隔加前导码的开销通常在几十字节量级,效率轻松跑到 95% 以上。无线不一样,一个数据帧从开始竞争到 ACK 结束,中间塞满了 DIFS、退避、前导码、SIFS、ACK,实际有效载荷占比经常只有一半上下。这也是为什么无线实测吞吐永远跑不满标称速率的根本原因——不是厂商虚标,是协议本身的开销就摆在那。

2. CSMA/CA 的完整时序:一次成功发送到底经历了什么

2.1 从“想发”到“发出去”:时间轴上的五个阶段

我习惯把一次成功的数据发送拆成五个阶段,讲给同事听的时候也是按这个顺序,比较好记。

阶段一,侦听。终端有帧要发,先看物理层是否空闲,同时检查 NAV 是否为 0。两个条件都满足才算信道空闲。

阶段二,等待帧间间隔。信道从忙变闲后,不能立刻发,必须先等一段固定的间隔,通常数据帧等的是 DIFS。这段等待的意义是给高优先级帧(比如 ACK、Beacon)让路——它们等的间隔更短,能抢先插进来。

阶段三,退避倒计时。DIFS 结束,进入退避流程。从竞争窗口里抽一个随机数作为退避时隙数,每个时隙减 1。这个倒计时有个特点:信道一忙就冻结,等下次空闲再接着减,不会重头开始。这一点很多人第一次接触时会搞混。

阶段四,发送数据帧。倒计时归零,立刻发。此时如果恰好有另一个终端也算到了 0,就撞了,双方都收不到 ACK。

阶段五,等 ACK。接收方校验 FCS 通过后,等一个 SIFS 立刻回 ACK。发方在 ACK timeout 内收到就结束,没收到就进入重传流程,竞争窗口翻倍。

这五步里,第三和第五是被问得最多的,下面单独展开。

2.2 帧间间隔不是随便定的:SIFS 与 DIFS 的优先级设计

帧间间隔(IFS)这套设计,本质上是一个不需要协商的优先级队列。谁的间隔短,谁就先开口。

SIFS(Short IFS)是最短的,用来处理一次交互中必须连续完成的动作:ACK、CTS、分片后的后续帧、以及聚合帧之间的响应。SIFS 短到什么程度?短到其他任何终端在 SIFS 期间都来不及完成“侦听—判断空闲—等待间隔—退避归零”这一整套流程,所以 SIFS 帧天然拥有最高优先级,不可能被打断。这就是“优先级”的实现方式:不靠令牌,靠时间差。

DIFS(DCF IFS)用于普通数据帧,长度等于 SIFS 加上两个时隙。这个“两个时隙”不是拍脑袋,它保证了在 SIFS 帧和 DIFS 帧之间至少有一次退避的机会,让竞争有序。

PIFS(PCF IFS)介于两者之间,历史上是给点协调功能用的,实际部署中很少见,了解即可。

EIFS是异常情况下用的,当终端收到一个无法解码的帧(比如 FCS 错误,或者它没听到前导码只听到了尾巴),它会认为信道状态异常,等一段比 DIFS 更长的 EIFS 再尝试,避免自己成为持续的干扰源。

具体数值跟频段和制式有关:

参数2.4GHz(802.11g/n)5GHz(802.11a/n/ac/ax)说明
时隙 Slot9 μs(部分老模式 20 μs)9 μs退避的时间粒度
SIFS10 μs16 μs最短帧间间隔
DIFS28 μs34 μsSIFS + 2 × Slot
典型 ACK 超时几十 μs 量级几十 μs 量级由速率和实现决定

注意 SIFS 在 5GHz 反而更长,因为高频段对定时精度的要求和实现代价不一样,标准就是这么定的。做室外长距离桥接的时候这个值还会被厂商放大,用来覆盖更长的传播时延,否则 ACK 根本来不及回来。这也是为什么“改时隙参数”在点对点远距离场景里是一个正经的调优手段,而在普通办公场景里是个坑。

2.3 随机退避怎么算:竞争窗口的翻倍规则

退避的核心是一个计数器。终端在 [0, CW] 区间里均匀取一个整数,CW 就是竞争窗口(Contention Window)。每过一个时隙,计数器减 1,减到 0 就发。

初始的 CW 等于 CWmin,失败一次之后按CW = min(2 × CW + 1, CWmax)扩大,这就是所谓的二进制指数退避。注意这里是 2×CW+1,不是简单地乘 2,因为窗口代表的是一段区间长度减一。

举个具体的:某终端第一次发送,CWmin=15,退避值在 0 到 15 之间取,平均等 7.5 个时隙。假设 2.4GHz 时隙 9μs,平均等待约 67.5μs。撞了一次,CW 变成 2×15+1=31,退避范围 0 到 31,平均 15.5 个时隙,约 139.5μs。再撞,CW=63,平均约 283.5μs。理论上最多退到 CWmax=1023,平均等待超过 4.6ms。这个增长曲线很陡,目的就是让重传越多次的终端越“谦让”,把信道让给状态好的终端。

这个设计的隐含假设是:碰撞大概率意味着参与竞争的终端多,所以大家都应该往后撤。但现实里还有另一种情况——碰撞是因为某个终端离得远、信号弱、或者被干扰,这时候指数退避反而让弱终端越来越难抢到机会,形成恶性循环。这个现象后面讲排查的时候还会提到。

2.4 ACK 与重传:MAC 层的最后一道防线

802.11 的 ACK 是单播帧的强制动作。接收方校验通过后,等 SIFS 立刻回一个短 ACK 帧。发方在 ACK timeout 内收到,本次传输结束;没收到,就认为失败。

失败的原因可能是碰撞,也可能是信道误码、干扰、或者对方根本没收到。协议层面不区分这些原因,统一按“失败”处理,扩大窗口重试。重试次数有上限,短帧和长帧分别有不同的重试限制,超过就丢弃并向上层报告。

这里有个容易忽略的细节:重传帧的 Duration 字段会让周围的终端更新 NAV,也就是说一次失败的重传会额外占用邻居的时间。在高密度场景里,重传率一高,整个小区的有效容量会被“看不见的时间”吃掉一大块。这也是为什么我排查无线问题时,Retry 率永远排在前三个要看的指标里。

3. 隐藏终端与 RTS/CTS:那个容易被误解的机制

3.1 隐藏终端的几何本质

隐藏终端不是“信号差”,而是“听不见但打得着”。设想一个 AP 在中间,A 终端在左边,B 终端在右边,A 和 B 相距较远,彼此的信号低于侦听门限,但都能以足够好的信噪比连上 AP。A 在发数据的时候,B 侦听信道是空闲的,于是 B 也发,两个信号在 AP 处叠加,双双失败。

这个问题的麻烦之处在于它跟“距离”不是单调关系。把 AP 功率调大,覆盖范围变大,隐藏终端反而更多;把终端功率调小,能缓解,但覆盖又不够。它是个拓扑问题,不是功率问题。

更隐蔽的是,隐藏终端造成的碰撞在统计上很“脏”:双方都收不到 ACK,都退避重传,退避窗口一起翻倍,然后可能再一次同步碰撞。这种“伪同步”会让某段时间内的失败率异常集中,看起来像是突发干扰,实际是拓扑导致的规律性碰撞。

3.2 RTS/CTS 握手与 NAV 的配合

RTS/CTS 的思路很直接:既然数据帧太长,撞了损失大,那就先发一个很短的控制帧试探。

发送方先发 RTS,里面带上这次传输预计占用的时长。接收方收到后回 CTS,CTS 里也带时长(而且比 RTS 里的略短一点,给 ACK 留出余量)。关键在于:CTS 是接收方发的,所以接收方周围的所有终端都能听到这个 CTS,包括那些听不到发送方的隐藏终端。它们读到 Duration 字段,把 NAV 设上,在这段时间里闭嘴。这就把隐藏终端从“不知道有人在发”变成了“知道有人在发”。

RTS/CTS 的代价也很明确:多了两个控制帧,多了一次 SIFS 往返。对于小包来说,这个开销占比高得离谱,反而不划算。所以标准里给了个 RTS 阈值(RTS Threshold),只有帧长超过阈值才启用握手。很多设备默认把阈值设成最大值,等效于关闭。

3.3 为什么现在大多数场景反而建议关掉它

我见过不少人一遇到丢包就把 RTS 阈值调到很低,觉得“开了握手就稳了”。实际测试下来,绝大多数室内场景这么做是负优化。

原因有这么几个。第一,现代 AP 的天线设计和功率控制比早期好很多,真正意义上的隐藏终端没那么常见,大多数所谓的“隐藏”其实是同频干扰或者非 Wi-Fi 干扰。第二,RTS/CTS 只在“有多个终端同时竞争同一段介质”时才有效,如果问题出在外部干扰源,握手帧自己也会被干扰打掉,等于白加开销。第三,高密度场景下 RTS/CTS 帧本身也在参与竞争,会显著抬高整体的信道占用时间,实测吞吐往往掉 10% 到 30%。

真正值得开 RTS/CTS 的场景我总结了三类:室外远距离点对点或点对多点桥接、大型仓储或厂房的稀疏大覆盖、以及明确抓到“两个固定终端反复同步碰撞”的小区。除此之外,我的默认建议是保持关闭,把精力放在降低同频干扰和调整功率上。

4. 参数计算与调优实战:把 CW、时隙、速率算明白

4.1 一次发送到底花了多少时间:手算一遍

不手算一遍,你对“开销”是没有体感的。我拿一个典型场景算:2.4GHz、802.11n、20MHz 带宽、单流、短保护间隔,物理速率 72Mbps,发一个 1500 字节的数据帧。

先算各段时长:

  • 数据帧内容 = 1500 字节负载 + 36 字节 MAC 头和 FCS = 1536 字节 = 12288 bit,按 72Mbps 算约 170.7μs。
  • 前导码和 PLCP 头,混合模式大约 40μs(含 L-STF、L-LTF、L-SIG 和 HT 相关字段)。
  • DIFS = 28μs。
  • 平均退避 = 7.5 个时隙 × 9μs = 67.5μs。
  • SIFS = 10μs。
  • ACK 帧按基本速率发,前导码加 14 字节,粗略 40μs 上下。

加起来约 356μs。有效载荷 12000 bit(1500 字节)除以 356μs,实际吞吐约 33.7Mbps。物理层标称 72Mbps,效率不到一半。

这个结果不是算错了,是真实的。剩下的时间全花在协调上。你把这个模型套到实际环境里,就能解释很多现象:为什么小包业务(语音、游戏、大量 ACK)的吞吐远低于大包业务;为什么开个视频会议,AP 上显示速率很高但用户体验很差。

4.2 帧聚合为什么是吞吐的分水岭

既然开销是固定的,那最直接的优化就是“一次多带点货”。A-MPDU 把多个 MPDU 聚合成一个物理帧发出去,共享同一套前导码、帧间间隔和退避。假设聚合 10 个 1500 字节的帧,前导码和退避这些固定开销被摊薄到十分之一,效率能从 47% 拉到 80% 以上。

这也是 802.11n 之后吞吐大幅提升的隐性原因之一——大家盯着 MIMO 和更高阶调制,其实聚合带来的效率提升同样关键。反过来说,如果你的业务全是小包(比如工业控制、语音),聚合根本用不上,那你在 802.11ac 上跑出来的实际吞吐可能还不如预期的一半。

4.3 一组可以直接落地的调优动作

下面这些是我在实际项目里反复验证过的动作,按收益从高到低排:

动作目的注意事项
关闭低速率(1/2/5.5/11Mbps)减少慢速帧占用信道时间先确认没有远距离或老设备依赖,否则会掉线
开启 A-MPDU / A-MSDU摊薄固定开销部分老终端兼容性差,需灰度
限制单 AP 关联终端数降低竞争强度一般控制在一个射频 30 到 40 台以内
2.4G 只开 1/6/11 三个信道避免同频重叠20MHz 带宽,别开 40MHz
调整发射功率与最小速率匹配缩小覆盖、减少远距离弱信号终端功率降了要同步检查边缘覆盖,避免掉线
RTS 阈值保持默认关闭避免额外握手开销仅在确认存在隐藏终端时打开

这里面最容易出事的是第一条。关低速率能显著改善整体效率,但如果有那么几台设备因为信号弱、只能靠低速率维持连接,你把低速率关了,它们就直接掉线,然后反复重连,反而制造更多管理帧风暴。所以做这一步之前,一定要先看关联终端的速率分布,确认低速率的占比和来源。

5. 抓包与现场排查实录

5.1 三个必须看的指标

无线排查最怕“凭感觉”。我现在的习惯是先看三个数,基本能定位到方向。

第一个是信道利用率(Channel Utilization)。这个值反映射频时间里有多少被占用。超过 60% 就该警惕,超过 80% 基本可以判定用户体验会明显下降。但要注意,利用率高不等于吞吐高——大量低速帧、管理帧、重传都会把利用率顶上去,实际有效吞吐却很可怜。

第二个是重传率(Retry Rate)。抓包看数据帧里的重传标志位,重传帧数除以总帧数。室内正常环境一般在 10% 以内,超过 20% 就说明碰撞或干扰严重。重传率高加上信道利用率高,基本就是“大家都在抢但都抢不到”的典型画面。

第三个是 CRC / FCS 错误率。这个指标区分了“碰撞”和“干扰”。碰撞导致的重传,帧本身是能被正确解码的(只是没收到 ACK);而 FCS 错误说明信号在传输过程中就被破坏了,多半是信噪比不够或者有非 Wi-Fi 干扰源。这两个原因的处理思路完全不同,前者要降竞争,后者要查干扰源、调功率、改信道。

5.2 一份现场排查的路径表

我把这些年遇到过的情况整理成一张速查表,遇到问题按这个顺序走,效率比乱试高得多:

现象优先怀疑排查动作处理方向
利用率高、吞吐低、重传高竞争过度看关联终端数和低速帧占比分流终端、关低速率、加 AP
利用率高、FCS 错误多外部干扰频谱扫描,看非 Wi-Fi 能量换信道、避开干扰源
部分终端反复掉线覆盖边缘看该终端 RSSI 和协商速率调功率、补点
单终端速度上不去但信号好协商速率或聚合未生效看 MCS、带宽、聚合状态检查终端能力、关闭兼容模式
语音卡顿但带宽充足竞争优先级看是否启用了 WMM 与优先级映射开启 WMM,正确标记 DSCP
大面积同时变慢上游或认证系统绕过无线直连测分段排查,别一上来就怪空口

5.3 几个踩过的坑

坑一:把信道利用率当成带宽利用率。早期我看到 80% 就以为快跑满了,赶紧申请扩容。后来才明白,利用率统计的是“射频忙的时间比例”,里面包含了前导码、帧间间隔、ACK、重传,有效载荷可能只占三成。真正该看的是有效吞吐和重传率的组合。

坑二:忽略管理帧的消耗。一个小区里如果有几十台终端频繁探测、漫游、重连,探测请求和响应帧会占掉可观的空口时间。尤其是有些终端在省电模式下反复唤醒扫描,看起来流量不大,实际对信道是持续的骚扰。后来我养成了看管理帧占比的习惯,超过 15% 就要查原因。

坑三:盲目调大退避参数。有一次为了缓解碰撞,我把 CWmin 调大了,碰撞确实少了,但小包业务的时延直接翻倍,语音质量反而更差。后来才想明白,退避窗口本质上是“用时间换成功率”,对时延敏感的业务是毒药。这类参数要按业务类型分开看,不能一刀切。

坑四:以为 5GHz 就没有隐藏终端。频段高、穿透差,覆盖范围小,隐藏终端的概率确实低,但在开阔的大空间里(比如展厅、仓库),终端之间互相听不见的情况依然存在。频段不解决问题,拓扑才解决问题。

6. 从 DCF 到 OFDMA:这套机制正在被怎么改写

6.1 高密度场景下 CSMA/CA 的天花板

CSMA/CA 是为“少量终端、突发业务”设计的。它的效率随终端数增加而急剧下降:终端越多,碰撞概率越高,退避窗口越大,空口时间越多地花在协调而不是传输上。有研究做过测算,在一个 BSS 内,活跃终端从 1 台增加到 30 台,聚合吞吐可能不升反降。

这就是为什么高密度场景(会议室、教室、体育馆)单靠加 AP 解决不了问题——加 AP 会引入更多的同频竞争,如果信道规划不好,反而互相拖累。真正的出路是减少“需要竞争的次数”。

6.2 BSS Coloring:让不相干的小区互不理会

802.11ax 引入的 BSS Coloring,思路是给每个 BSS 打一个颜色标记,写在物理帧头里。终端收到帧后先看颜色:如果是自己小区的,按原来的规则处理;如果是别的颜色,且信号强度低于某个阈值,就可以认为“这个传输跟我没关系”,提前结束 NAV,照常发送。

这一招把“只要听到就退让”改成了“听到但离得远就不退让”,本质上是放宽了空间的复用条件。实测在高密度部署里,开启后同频小区的并行传输机会明显增加,边缘用户的体验改善比较直观。但它对信道规划和功率控制的要求更高,颜色配错或者阈值设歪了,会引入新的碰撞。

6.3 OFDMA 与 TWT:把“抢”变成“分”

OFDMA 是另一个方向的思路转变。原来的竞争是“整段时间、整个信道”的争夺,OFDMA 把信道切成资源单元(RU),一个传输机会里可以同时服务多个终端,各占一块子载波。这样多个小包终端不必挨个排队竞争,AP 一次调度就能把它们打包发完。

TWT(目标唤醒时间)则是从时间维度减少竞争。AP 和终端协商好什么时候醒、什么时候睡,大量物联网设备不再需要频繁醒来抢信道,探测帧和竞争帧的数量大幅下降。这两个机制配合起来,才是高密度场景真正的解法——不是让竞争更公平,而是让竞争这件事本身变少。

不过要说清楚,OFDMA 和 BSS Coloring 并没有推翻 CSMA/CA,它们是在其之上做优化。信道接入的基本框架还是“侦听—退避—确认”,只是侦听的判断更聪明、退避的粒度更细、确认的方式更灵活。理解底层机制依然是理解这些新特性的前提。

最后分享一个我自己的习惯:每次做完一轮无线优化,我都会留一份优化前的抓包和关键指标快照,优化后再抓一份对比。不是为了交报告,是因为无线环境是动态的,过两周出问题时,你很难凭记忆判断“到底是变差了还是本来就这样”。有了基线,判断会快很多。另外一个体会是,遇到无线问题先别急着动参数,把“是覆盖问题、干扰问题还是竞争问题”这三者分清楚,方向对了,后面的动作才有意义。参数是最后的微调手段,不是第一反应。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进