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(检测)。
它的基本流程是这样的:
- 先听(Carrier Sense):发数据前,先监听信道。如果信道忙,就等着。
- 随机退避(Random Backoff):信道空闲后,不能马上发,得等一个随机时间。这个时间叫退避时间。
- 发前握手(Optional RTS/CTS):可选步骤,先发一个“我要发了”的短帧,对方回一个“你发吧”,这样其他人就知道要避让了。
- 发完等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的完整发送流程:
这个流程看起来复杂,但核心逻辑很简单:先听后说,说前先等,等完再说,说错重来。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层的“税”。