20、WiFi调试:wpa_supplicant、WiFi扫描、连接问题、吞吐量测试
WiFi调试,说难不难,说简单也不简单。我见过不少开发同事,遇到WiFi连不上就重启手机,遇到网速慢就怪路由器。其实,Android系统里WiFi的整个流程是清晰可循的。今天我们就把它拆开来看。
20.1 核心组件:wpa_supplicant
wpa_supplicant 是 WiFi 连接的大脑。它运行在用户空间,负责处理认证、密钥协商、漫游等脏活累活。说白了,它就是 WiFi 协议栈的“外交官”。
我个人习惯,遇到 WiFi 连接问题,第一件事就是看 wpa_supplicant 的日志。怎么抓?很简单:
adb shell logcat -b main -s wpa_supplicant
或者更直接一点,看它的专属日志:
adb shell logcat -b main -s wpa_supplicant:*
你会看到类似这样的输出:
I/wpa_supplicant( 1234): wlan0: Trying to associate with xx:xx:xx:xx:xx:xx (SSID='MyWiFi' freq=2412 MHz)
I/wpa_supplicant( 1234): wlan0: Associated with xx:xx:xx:xx:xx:xx
I/wpa_supplicant( 1234): wlan0: WPA: Key negotiation completed
I/wpa_supplicant( 1234): wlan0: CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed [id=1 id_str=]
嗯,这里要注意:如果卡在“Trying to associate”这一步,通常是信号太弱或者密码不对。如果卡在“Key negotiation”,那多半是加密方式不匹配。
adb shell wpa_cli log_level DEBUG。不过记得调回来,否则日志会刷屏。
20.2 WiFi扫描:从被动到主动
WiFi扫描分两种:主动扫描和被动扫描。主动扫描是手机发 Probe Request,AP 回 Probe Response。被动扫描是手机听 Beacon 帧。
Android 系统默认是主动扫描。你想想看,手机每隔一段时间就会发一次 Probe Request,看看周围有哪些 AP。这个间隔通常是 10 到 30 秒。
我在项目中遇到过一个问题:某款手机在商场里 WiFi 列表刷不出来。查了半天,发现是扫描间隔被系统电源管理模块拉长了。因为商场里 AP 太多,扫描太频繁会耗电。解决方案是调低扫描的退避算法阈值。
扫描相关的关键日志:
D/WifiScanning( 5678): Starting scan for 1234567890ms
D/WifiScanning( 5678): Scan completed in 350ms, found 12 APs
如果扫描时间过长(比如超过 1 秒),或者找到的 AP 数量异常少,那就要怀疑硬件或者驱动问题了。
ACCESS_FINE_LOCATION 权限。
20.3 连接问题:常见坑与排查思路
连接问题是最让人头疼的。我总结了几种常见场景:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 连接超时 | 信号弱、AP 负载高、信道干扰 | 看 wpa_supplicant 日志,检查 RSSI |
| 频繁断连 | 漫游策略问题、AP 信号不稳定 | 抓取 dumpsys wifi,看 roam 记录 |
| 能连上但没网 | DHCP 失败、DNS 解析问题 | 检查 /data/misc/dhcp/dhcpcd-*.lease |
| 密码正确但连不上 | 加密方式不匹配、PMF 设置冲突 | wpa_supplicant 日志里看 EAP 协商 |
我曾经遇到一个奇葩问题:某款路由器开启了 802.11r 快速漫游,但手机不支持。结果每次连接都要反复握手 3 次才能成功。最后在 wpa_supplicant 配置里加了 disable_11r=1 才解决。
排查连接问题的黄金命令:
adb shell dumpsys wifi | grep -A 20 "mWifiInfo"
这个命令会输出当前连接的详细信息,包括 RSSI、链路速度、频段、认证类型等。如果 RSSI 低于 -70 dBm,那信号就偏弱了。
20.4 吞吐量测试:不只是测速
吞吐量测试,很多人以为就是打开 Speedtest 跑一下。其实不然。吞吐量测试要分场景:上行、下行、双向、不同包大小、不同信道环境。
我常用的工具是 iperf3。它比 Speedtest 更可控,能精确测量 TCP/UDP 吞吐量。用法如下:
在 PC 上启动服务端:
iperf3 -s -i 1
在手机上启动客户端:
iperf3 -c 192.168.1.100 -t 30 -i 1
输出示例:
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 11.2 MBytes 94.0 Mbits/sec
[ 5] 1.00-2.00 sec 10.8 MBytes 90.6 Mbits/sec
[ 5] 2.00-3.00 sec 11.5 MBytes 96.5 Mbits/sec
如果吞吐量波动很大,比如从 90 Mbps 突然掉到 20 Mbps,那说明信道有干扰或者 AP 在切换信道。
还有一个容易被忽略的点:TCP 窗口大小。Android 默认的 TCP 缓冲区可能偏小,影响高延迟场景下的吞吐量。可以用 sysctl 查看:
adb shell cat /proc/sys/net/ipv4/tcp_rmem
adb shell cat /proc/sys/net/ipv4/tcp_wmem
如果发现值偏小,可以尝试调大。不过要注意,这需要 root 权限。
20.5 知识体系总览
下面这张图,是我自己整理的 WiFi 调试知识体系。你可以把它当作一个检查清单:
这张图把 WiFi 调试分成了四个维度。我个人习惯,遇到问题先看 wpa_supplicant 日志,再检查扫描结果,然后分析连接过程,最后才测吞吐量。顺序很重要,不要跳步。
好了,WiFi 调试这块,核心就是这几个点。记住:日志是基础,工具是辅助,经验是加速器。多动手,多总结,你也能成为 WiFi 调试的老手。
公众号:蓝海资料掘金营,微信deep3321