4. WiFi MAC层:CSMA/CA机制、帧结构(管理帧/控制帧/数据帧)、DCF与EDCA

各位好,欢迎来到第四章。这一章我们聊聊WiFi的MAC层,也就是介质访问控制层。说白了,就是解决“谁先说话”的问题。

有线网络很简单,插根网线,谁想发就发,撞了再说(CSMA/CD)。但无线不一样,你发信号的时候,自己根本听不到别人在发——这叫“半双工”和“自干扰”。所以WiFi不能靠“撞了再退”,得靠“发之前先听”。这就是CSMA/CA的由来。

核心一句话:CSMA/CA就是“先听后说,说前先等,等完再说,说错重来”。

4.1 CSMA/CA:先听后说,说前先等

CSMA/CA全称是Carrier Sense Multiple Access with Collision Avoidance。注意最后两个字母——CA是Avoidance(避免),不是Detection(检测)。

它的基本流程是这样的:

  1. 先听(Carrier Sense):发数据前,先监听信道。如果信道忙,就等着。
  2. 随机退避(Random Backoff):信道空闲后,不能马上发,得等一个随机时间。这个时间叫退避时间。
  3. 发前握手(Optional RTS/CTS):可选步骤,先发一个“我要发了”的短帧,对方回一个“你发吧”,这样其他人就知道要避让了。
  4. 发完等ACK:发完数据帧,必须等对方回ACK。没收到就重传。

嗯,这里要注意:退避时间不是固定的。每次重传,退避窗口会翻倍。这就是二进制指数退避。我第一次调WiFi吞吐时,发现重传率一高,延迟就爆炸,后来才意识到是退避窗口太大导致的。

避坑指南:我曾经在密集AP部署场景下,发现某个AP的吞吐特别低。抓包一看,退避时间一直在最大值附近徘徊。原因是周围AP太多,信道几乎没空闲过。后来调整了CCA阈值,才把吞吐拉回来。

4.2 帧结构:WiFi的“信封”长什么样

WiFi MAC层有三种帧类型:管理帧、控制帧、数据帧。每种帧都有自己的格式,但都共享一个通用的帧头结构。

先看通用帧头:

| Frame Control (2B) | Duration/ID (2B) | Address 1 (6B) | Address 2 (6B) | Address 3 (6B) | Sequence Control (2B) | Address 4 (6B) | ...

Frame Control字段里有个Type和Subtype,用来区分帧类型。我习惯用Wireshark直接看这个字段,比背二进制快多了。

帧类型 Type值 常见子类型 用途
管理帧 00 Beacon, Probe Request/Response, Association 连接管理、扫描、同步
控制帧 01 RTS, CTS, ACK, Block ACK 信道握手机制、确认
数据帧 10 Data, Null Data, QoS Data 承载上层数据

4.2.1 管理帧:WiFi的“社交礼仪”

管理帧负责建立和维护连接。最常见的几个:

  • Beacon帧:AP每隔100ms广播一次,告诉周围“我在这里,我叫XX,我支持这些速率”。
  • Probe Request/Response:STA主动扫描时发的“有人吗?”和AP回的“我在呢”。
  • Association Request/Response:连接建立时的握手帧。

我记得有一次排查WiFi漫游问题,抓包发现STA一直在发Probe Request,但AP就是不回Probe Response。后来发现是AP的SSID隐藏了,Probe Response被防火墙过滤了。嗯,这种坑踩过一次就记住了。

4.2.2 控制帧:WiFi的“交通指挥”

控制帧不携带用户数据,只负责协调信道访问。核心三个:

  • RTS/CTS:解决隐藏节点问题。A发RTS给AP,AP回CTS给所有人,其他人听到CTS就闭嘴。
  • ACK:收到数据帧后必须回ACK,否则发送方会重传。
  • Block ACK:802.11e引入的优化,一次确认多个帧,减少ACK开销。

注意:RTS/CTS虽然能解决隐藏节点,但会引入额外开销。在干扰小的环境下,建议关闭RTS/CTS。我一般把RTS阈值设成2347(最大值),相当于禁用。

4.2.3 数据帧:真正的“货物”

数据帧承载IP包。802.11数据帧有四种地址字段:

  • Address 1:接收端(RA)
  • Address 2:发送端(TA)
  • Address 3:最终目的或源(取决于To DS/From DS位)
  • Address 4:仅在WDS桥接模式下使用

你想想看,一个数据帧里塞了四个MAC地址,是不是比以太网复杂多了?这就是无线网络的代价——因为数据要经过AP中转,地址关系更复杂。

4.3 DCF与EDCA:两种“排队”策略

DCF(Distributed Coordination Function)是基础版的信道访问机制。EDCA(Enhanced Distributed Channel Access)是QoS增强版。

4.3.1 DCF:公平但粗糙

DCF就是前面讲的CSMA/CA基本流程。所有站点平等竞争,谁退避时间先到谁先发。优点是公平,缺点是没有优先级。

DCF的关键参数:

  • DIFS:DCF帧间间隔,固定值(50μs for 802.11b)
  • SIFS:短帧间间隔,用于ACK、CTS等高优先级响应(10μs)
  • CWmin/CWmax:竞争窗口的最小值和最大值

举个例子:你家里两台电脑同时下载,DCF会让它们轮流发,谁也不会饿死。但如果有一台在打VoIP电话,语音包需要低延迟,DCF就不行了——语音包和下载包得一起排队。

4.3.2 EDCA:给不同业务“插队”

EDCA是802.11e引入的,把数据分成四个接入类别(AC):

接入类别 典型业务 CWmin CWmax AIFSN TXOP Limit
AC_VO(语音) VoIP 3 7 2 1.5ms
AC_VI(视频) 视频流 7 15 2 3.0ms
AC_BE(尽力而为) 网页浏览 15 1023 3 0
AC_BK(背景) 文件下载 15 1023 7 0

你看,语音类的CWmin只有3,退避时间很短,几乎不用等就能发。而背景类的CWmin是15,退避时间长,得等别人发完才能轮到自己。

我个人习惯在测试WiFi语音质量时,先检查EDCA参数是否配置正确。有一次客户投诉语音断续,抓包发现AC_VO的CWmin被设成了15,相当于语音包和下载包在同一个优先级竞争,不卡才怪。

4.4 核心流程:从退避到发送

下面这张图展示了DCF/EDCA的完整发送流程:

DCF/EDCA发送流程 DCF/EDCA 发送流程 监听信道 信道空闲? 等待AIFS/DIFS 随机退避 发送数据 等待ACK 收到ACK? 发送成功 重传(退避加倍) 说明 虚线表示重传后回到退避阶段 退避窗口每次翻倍(CW×2)

这个流程看起来复杂,但核心逻辑很简单:先听后说,说前先等,等完再说,说错重来。EDCA就是在“等”这一步加了优先级——语音等得短,下载等得长。

4.5 实战:抓包看CSMA/CA

我建议你打开Wireshark,抓一个WiFi空口包,然后过滤 wlan.fc.type 看看:

  • wlan.fc.type == 0:管理帧(Beacon、Probe等)
  • wlan.fc.type == 1:控制帧(RTS、CTS、ACK)
  • wlan.fc.type == 2:数据帧

你想想看,一个正常的WiFi环境里,管理帧和控制帧能占到30%~50%的空中时间。这就是为什么WiFi效率低——大量时间花在握手和确认上,而不是传数据。

实战技巧:我曾经用Wireshark统计过,一个802.11n的40MHz信道,理论吞吐150Mbps,实际只能跑到70Mbps左右。刨去管理帧、控制帧、退避时间、重传,真正传数据的效率也就50%左右。这就是MAC层的“税”。