Wi-Fi帧间间隔全解析:从SIFS到EIFS,读懂DCF的微秒级优先级
做 Wi-Fi 抓包和协议分析这些年,我经常被问一个问题:数据帧发完以后,ACK 为什么能这么快回来?明明大家都是抢信道,凭什么它不排队?答案就在今天要聊的帧间间隔(Interframe Space,IFS)里。帧间间隔是 802.11 MAC 层最基础、也最容易被忽略的一组时间参数,DCF(分布式协调功能)里的接入流程、优先级关系、退避机制,全都建立在它上面。只要这几个微秒级的数字不对,整个 Wi-Fi 网络的公平性和效率就会跟着崩。
这篇文章是 Wi-Fi MAC 层学习系列的第 11 篇,专门讲 DCF 的帧间间隔。我会从 CSMA/CA 的整体思路讲起,把 SIFS、PIFS、DIFS、EIFS 四种间隔逐一拆开,告诉你标准为什么要这样取值,然后分享抓包时怎么把这些参数“看”出来,最后给一份实战中排查帧间间隔异常的经验清单。适合正在啃 802.11 协议的工程师、做无线网络优化的同学,也适合被“Wi-Fi 延迟高、重传高”折磨的运维朋友。
1. DCF 的宏观角色:没有交警的十字路口
1.1 CSMA/CA 的基本逻辑
Wi-Fi 和有线网络最大的不同,就是它没有一个可以“同时收发”的双向通道——绝大多数情况下一个信道同一时刻只能有一个站点在发。AP 和客户端都在同一个频段上工作,谁先说话、谁说多久,必须有规矩。DCF 就是这套规矩的基石:所有站点采用 CSMA/CA(载波侦听多路访问/冲突避免),发之前先听,信道空了再发。
但“先听后发”有个致命问题:两个站点可能同时听到信道空闲,然后同时发送,产生碰撞。有线以太网碰一下就碰一下,CSMA/CD 可以边发边听并及时检测;Wi-Fi 做不到,因为无线收发无法同时进行,等你发现自己撞了,数据已经毁了。802.11 的解决办法是“避免”:发送之前不仅要听,还要等一个统一的最短时间,再叠加一段随机退避时间。这个“统一的最短时间”,就是 DIFS;“随机退避”就是基于 slot 的指数退避算法。
1.2 IFS 在 DCF 中的位置
IFS 在整个 DCF 流程里承担两个功能。第一个是“把不同的帧类型排出先后顺序”:ACK、CTS 这类响应帧必须比普通数据帧更早发出来,否则整个交换流程会被旁站打断。第二个是“给退避算法提供时间刻度”:站点在退避时按 slot 递减计数器,而每次从信道忙转到空闲,都必须重新确认 DIFS/AIFS 是否已经满足。可以这么说,DCF 的时间轴就是由一段段 IFS 拼接而成的。
你用“帧间间隔”在资料里搜,通常会看到一张表列出四个数值。但要把它们记牢,不能只背数字,而是要理解为什么要有这么多个不同的值,它们之间的差又是怎么算出来的。下面我按从短到长的顺序逐一拆。
2. 四种帧间间隔,各自都在等什么
2.1 SIFS:给“最该回应的人”开特权通道
SIFS(Short Interframe Space,短帧间间隔)是 802.11 里最短的间隔,OFDM 系 PHY 一般取 16μs,DSSS/CCK 的 802.11b 取 10μs。它的使用场景非常有针对性:收到单播数据帧后回 ACK、收到 RTS 后回 CTS、以及 PCF/HCCA 模式下的轮询响应。换句话说,SIFS 基本是给“上一帧指定的接收者”用的。
为什么响应帧有资格插队?因为当站点 A 给站点 B 发了一个单播帧,只有 B 能确认这个帧有没有被正确收到;如果 B 要等跟其他人一样的 DIFS 再回 ACK,别的站点可能先抢到信道,A 就一直收不到确认,只能重传。SIFS 比 DIFS 短得多,这就保证 B 一定是第一个拿到信道的站点。这叫“用时间差制造优先级”,是整个 DCF 设计里最巧妙的部分。
2.2 PIFS:给控制器留的专用档期
PIFS(PCF Interframe Space)是 SIFS 加一个 slot 的时间,OFDM 下约 25μs。它本来是为 PCF(点协调功能)服务的:网络里的点协调器(通常集成在 AP 里)可以只等 PIFS 就抢信道,而普通 DCF 站点要等 DIFS,所以控制器永远排在普通站点前面。
实际部署中 PCF 基本没有大规模落地,802.11e 之后被 HCCA/EDCA 取代,但 PIFS 并没有消失。在很多协议实现里,它仍然作为“优先接入”的时间基准存在。学习的时候不必把它看得太重,但要知道在 IFS 的优先级阶梯里,它是承上启下的那一级。
2.3 DIFS:普通数据帧的地板价
DIFS(DCF Interframe Space,DCF 帧间间隔)是普通数据帧发送前必须满足的最短空闲时间,公式是 DIFS = SIFS + 2 × Slot。OFDM 下是 34μs,802.11b 是 50μs,纯 802.11g 不开保护模式时是 28μs。注意,DIFS 更准确的说法是“数据帧接入的最低门槛”:想用 DCF 发数据帧,信道必须先空闲至少 DIFS。
关键问题来了:为什么是 SIFS 加两个 slot,而不是一个?如果 DIFS 只比 SIFS 多一个 slot,那么 ACK 发完后,等了一个 slot 的普通站点就能马上开始退避或传输,留给 ACK 的“安全区”太短;万一旁边站点的时钟、传播时延和接收切换存在误差,很容易一头撞在 ACK 上。取两个 slot 既保证 SIFS 响应能干净利落地完成,又不会让信道白白浪费太久。
2.4 EIFS:听不懂的时候,宁可多等一会儿
EIFS(Extended Interframe Space,扩展帧间间隔)可能是最容易被忽略的一个。它的触发条件不是“我要发送”,而是“我刚才收到了一帧坏数据”——比如 FCS 校验失败、速率不识别、物理层报错。公式是 EIFS = SIFS + DIFS + 发送一个 ACK 所花费的时间(按基本速率计算)。按 OFDM 基本速率 6Mbps 算,大约在 90~100μs 级别;在 802.11b 的 1Mbps 长前导下,可能超过 300μs。
为什么要等这么久?设想一下:你听到了一个残缺的帧,但你不知道它里面的地址、时长字段是什么,所以你不知道是不是有另一个站点正准备回 ACK。为了避免你冒然出手,把一段本该完整进行的交换打断,标准让你多等一会儿,等到“如果它是有效帧,它该收到的 ACK 早已发完”的时间点,再恢复正常退避流程。EIFS 是一种“因为无知所以保守”的机制。
| 间隔 | 关系 | OFDM(11a/n/ac/ax) | 802.11b | 主要用途 |
|---|---|---|---|---|
| SIFS | 最短 | 16μs | 10μs | ACK、CTS 等响应帧 |
| PIFS | SIFS + 1×Slot | 25μs | 30μs | PCF/HCCA 控制器接入 |
| DIFS | SIFS + 2×Slot | 34μs | 50μs | 普通数据帧接入门槛 |
| EIFS | SIFS + DIFS + ACK 时长 | 90μs 起 | 300μs 级 | 收到错误帧后的退让 |
3. 隐藏在数值背后的协议设计逻辑
3.1 SIFS 为什么必须留出“切换时间”
SIFS 的取值不是拍脑袋定的。802.11 标准在定义 SIFS 时,要求它至少能覆盖三部分开销:物理层从接收切换到发送的时延(RX/TX turnaround,OFDM 下约 2μs)、MAC 层处理一帧并生成响应的处理时间、以及电磁波在空气中的传播时延。也就是说,B 收到 A 的最后一比特后,经过前导码捕获、CRC 校验、驱动丢包处理等一系列动作,还要能在 SIFS 内把 ACK 发出去。
在硬件实现里,SIFS 是硬实时约束。我之前调过一款 Wi-Fi 模组,固件里 ACK 生成路径走了软件队列,结果空口测量 SIFS 时常超过 25μs,旁边的站点等完 DIFS 就开始抢信道,最终表现就是重传率飙升、吞吐只有正常值的一半。这种问题看抓包很难定位,必须拿示波器或者专业空口抓包工具做时序测量。经验是:如果发现数据帧和 ACK 之间出现超过 DIFS 的“慢 ACK”,先怀疑驱动路径和省电模式,不要一上来就动射频参数。
3.2 Slot Time 是怎么凑出来的
Slot Time(时隙)是退避算法的最小时间单位,不是随便定的。它必须保证:任何两个站点对“信道是否空闲”的判断结果,不因为物理差异出现严重的不一致。OFDM 的 9μs 大致由这几块组成:CCA 检测时间(约 4μs)、RX/TX 切换时间(约 2μs)、同 BSS 范围的传播时延(数百米约 1~2μs),再留一点 MAC 处理余量。DSSS 需要 20μs,是因为 802.11b 的 CCA 机制更长。
这个“一致性”特别关键。退避的规则是所有站点在信道空闲时按 slot 递减计数器,如果有人因为物理层能力差、判断慢,比其他人晚看到信道空闲,它就会在一个 slot 里“滞后”,等它数到 0 发送时,别人可能也刚好在发,碰撞概率直接上升。标准把 slot 取大一点,就是给所有站点一个同步窗口。
3.3 优先级阶梯:为什么 ACK 一定抢得过数据帧
把四种 IFS 放在一起,就是一个天然的优先级阶梯:SIFS < PIFS < DIFS < EIFS。DCF 没有中心调度器,也不存在“令牌”,它保持公平性的武器就是让不同类型的帧等在位数不同的时间上。帧交换序列(比如 RTS/CTS/Data/ACK)之所以能像一个原子操作一样一气呵成,靠的就是 SIFS 的插队特权。
再加上 Duration/ID 字段设置 NAV(网络分配向量),整个交换周期在时间上就被“双重锁死”了:数据帧开始前,响应方用 SIFS 抢到信道;一旦帧里带上了时长信息,其他听到的站点即使没在等 DIFS,也会因为 NAV 而沉默。这两层机制加在一起,才能保证复杂的四步握手不被第三方打断。
3.4 EDCA 如何把 DIFS 改成分优先级等待
802.11e/WMM 引入 EDCA 后,DIFS 的角色被 AIFS(Arbitration IFS)接过。AIFS 的公式是 AIFS = SIFS + AIFSN × Slot。默认参数里,语音和视频接入类别的 AIFSN=2,尽力而为是 3,背景流量是 7。注意 AIFS 仍然保持了“SIFS 最短”的原则,ACK、CTS 依旧走 SIFS,所以响应帧优先级的根基没有动摇。
这也解释了为什么 2.4GHz 的混合环境里,把 802.11b 保护模式关掉后吞吐会明显变好:保护模式下 slot 从 9μs 拉长到 20μs,AIFS、DIFS 和退避时间全部跟着变长,信道空转时间大幅增加。如果网络里确实没有 b 老设备,关掉兼容模式往往是最划算的优化。
4. 抓包观测帧间间隔的方法和实测记录
4.1 准备一个“时间戳可靠”的抓包环境
想观察帧间间隔,第一原则是别用普通 USB 网卡抓 802.11 时序。很多 USB 网卡的时间戳精度只能到 1ms 甚至更低,连判断 SIFS 到底是 16μs 还是 50μs 都做不到。有条件的话用支持 monitor mode 的笔记本内置无线网卡,配合打了补丁的 Linux 驱动(比如某些老款 Intel、Atheros 芯片),时间戳能到微秒级;要更精确的空中时序,就得用支持精确时间戳的专业工具或专用抓包器。
我自己的常用组合是:Linux 下用 iw 把网卡切到 monitor mode,Wireshark 抓 pcap,然后在显示设置里把时间列换成“Seconds since previous captured frame”。这样每一帧之间的时间差就直接显示成秒的小数,能看到 0.000016 这种数字,说明抓到了微秒级间隔。
4.2 在 Wireshark 里定位关键帧对
先筛出想要看的帧。常用的过滤器:
- ACK:
wlan.fc.type_subtype == 0x1d - CTS:
wlan.fc.type_subtype == 0x1c - RTS:
wlan.fc.type_subtype == 0x1b - QoS Data:
wlan.fc.type_subtype == 0x28
拿一次 RTS/CTS/Data/ACK 四步交换为例,把过滤器设置为 AND 关系,配合时间列,能看到大体这样的顺序:
RTS →(约 16μs)→ CTS →(约 16μs)→ Data →(约 16μs)→ ACK
如果抓包工具时间戳足够好,理论上这中间的三段“空白期”都应该接近 SIFS。实测中因为驱动处理、PHY 准备、信道忙等噪声,通常会比理论值多个 5~20μs,这都算正常。真正需要注意的是“超过 DIFS 甚至超过 40μs+ 的间隔”,那通常意味着信道被别的东西占用、退避被冻结,或者 ACK 路径出了问题。
4.3 实测中看到的“时间膨胀”现象
我在一个办公室环境里做过一次 5GHz 抓包,环境里有三四个 AP、二十多台终端。抓下来的数据帧和 ACK 间隔很少是干净的 16μs,更多是 20~40μs 的“时间膨胀”。分析下来,主要原因有三个:一是该网卡自身处理延迟加上驱动时间戳偏移;二是信道在帧间被其他信号占了一下,虽然 DCF 正在 SIFS 等待期内不受影响,但如果是 ACK 之后的数据帧发送,就可能进入退避;三是部分终端没有完全按标准在 SIFS 内回 ACK。
这类实测数据提醒我,别把某个值直接当作“设备不合格”的判据。应该看的是统计分布:大量 ACK 都挤在 40μs 开外,才值得深挖;个别偏离说明不了什么。每次我做完这种观测,都会顺手记录一下环境里的信道利用率和重传率,这两个数字能帮你区分“时间膨胀是正常的接入竞争”还是“设备行为有问题”。
4.4 别被抓包工具的“伪SIFS”带偏
抓包工具的帧时间戳,代表的是“这个帧被网卡接收并交给协议栈的时间”,不等于“这个帧在空口上开始发送的时间”。尤其在重负载环境下,驱动会排队,帧时间戳会整体前移或后移。更坑的是有些抓包网卡会自动做帧聚合、去重、重排序,时间戳连相对位置都可能不准。
所以我的习惯是:第一,抓包永远配合 AP 侧的芯片统计看,而不是只看 pcap;第二,如果要严谨测量 IFS,把抓包网卡固定在一个信道,排除扫描和切换带来的时间戳跳变;第三,千万不要因为某一次抓包看到“SIFS 变成了 3μs”就下结论,那大概率是时间戳截断、四舍五入或者网卡 bug。
5. 实战:帧间间隔异常排查清单与调优心得
5.1 常见问题速查表
| 现象 | 可能原因 | 排查建议 |
|---|---|---|
| ACK 与数据帧间隔明显大于 SIFS | 驱动/固件处理慢、省电模式、信道被占 | 检查重传率、关闭省电、换高性能网卡/AP |
| 抓包看到大量退避空闲 | 高负载下正常竞争 | 结合信道利用率判断,不必过度处理 |
| 收错帧后长时间沉默 | EIFS 机制生效,属正常 | 重点查误码率、干扰源 |
| b/g 混合网络性能差 | 保护模式把 slot 拉到 20μs | 评估能否关闭 b 速率和 protection |
| 个别终端表现异常,ACK 极其慢 | 非标设备或省电调度 | 用频谱仪+协议分析定位设备 |
5.2 影响 SIFS 达标的工程细节
实际工程里,最容易让 SIFS 不达标的是省电模式和中断延迟。站点从 doze 状态醒来后,需要重新同步时间、切换射频,这时要它在一个 SIFS 内回 ACK 几乎不可能。所以很多协议栈的实现是“如果预测到即将 sleep,就不要接收单播帧”,或者干脆在醒来后的第一段时间只接收不发。你在抓包里如果看到某个终端总是“慢半拍”,先看看它的 Power Management 位是不是频繁置 1。
另一个常见点是 802.11n/ac 时代的 A-MPDU。聚合帧内部多个 MPDU 之间没有帧间间隔,它们会在一个 PPDU 里连续传;而连续两个 PPDU 之间如果需要保持序列,仍然要用 SIFS 来衔接。早期 802.11n 还短暂定义过更短的 RIFS(2μs)用于突发,后来因为与传统设备的共存性太差,标准和主流实现都放弃了它。现在主流的做法就是老老实实用 SIFS,一旦 SIFS 被破坏,本来一次能发的聚合会被拆散,空口效率掉得很快。
5.3 调优方向与亲测心得
我觉得帧间间隔相关的调优,收敛到最后就三件事:缩短无谓的等待、减少无用的退避、让响应帧快速发出。具体操作上,我比较推荐按优先级来做:
先确认 2.4GHz 是不是真的需要兼容 802.11b,如果不需要,关掉 b 速率和 protection,把 slot 从 20μs 降回 9μs。这是我做过收益最明显的一次优化,单终端吞吐涨了差不多三成。
再检查 AP 的 EDCA 参数,尤其是 VoIP 和视频流有没有被默认参数拖累。AIFSN、CWmin/CWmax 这些是合法可调的,不要动 SIFS 和 slot,那是标准层面的物理时序,乱改只会把整个 BSS 的兼容性搞坏。
最后看环境里有没有大量低速率站点。低速率站点会占用很长的发送时间,变相拉长其他站点的等待,和 IFS 参数本身无关,但对“延迟升高”的体感影响最大。这个层面的问题,靠抓包看不全面,建议结合 AP 侧每个速率等级的收发统计一起看。
我自己的体会是,帧间间隔看似是几个固定数字,实际上它是 802.11 整个 MAC 层公平性设计的浓缩。真出问题时,先看 IFS 是否被破坏,再看退避参数和站点调度,最后才轮到射频指标。那些一上来就怀疑天线、怀疑遮挡的排查思路,往往绕了远路。