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”,那多半是加密方式不匹配。

我的小技巧: 在调试时,可以临时把 wpa_supplicant 的日志级别调到 DEBUG,能看到更多握手细节。命令是: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 数量异常少,那就要怀疑硬件或者驱动问题了。

注意: Android 8.0 之后,扫描权限被严格限制。第三方应用不能随意触发扫描,否则会被系统拦截。调试时如果发现扫描结果为空,先检查一下应用是否有 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 在切换信道。

关键指标: 2.4 GHz 频段,理论最高 300 Mbps,实际能到 80-100 Mbps 就算不错。5 GHz 频段,理论 867 Mbps,实际 400-500 Mbps 算正常。如果差太多,先检查是不是用了老旧设备或者信道拥堵。

还有一个容易被忽略的点: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 扫描 连接问题 吞吐量测试 日志抓取 认证协商 配置管理 主动/被动 扫描间隔 权限问题 信号弱 频繁断连 DHCP失败 iperf3 工具 TCP/UDP 测试 窗口调优 日志 + 工具 + 经验 = 高效调试

这张图把 WiFi 调试分成了四个维度。我个人习惯,遇到问题先看 wpa_supplicant 日志,再检查扫描结果,然后分析连接过程,最后才测吞吐量。顺序很重要,不要跳步。

避坑指南: 我曾经在调试吞吐量时,发现手机和路由器之间隔了一堵承重墙,结果 5 GHz 信号衰减到 -80 dBm,吞吐量只有 10 Mbps。后来换了 2.4 GHz,虽然速度慢点,但至少稳定。所以,调试前先确认物理环境。

好了,WiFi 调试这块,核心就是这几个点。记住:日志是基础,工具是辅助,经验是加速器。多动手,多总结,你也能成为 WiFi 调试的老手。


公众号:蓝海资料掘金营,微信deep3321