wlanenuminterfaces函数用于枚举本地计算机上当前启用的所有无线lan接口,需先调用wlanopenhandle获取有效句柄,参数preserved必须为null,成功时返回error_success并分配ppinterfacelist内存,使用后须调用wlanfreememory释放。

Windows平台用WLAN API枚举SSID需要先打开适配器句柄
直接调用 WlanEnumInterfaces 前必须用 WlanOpenHandle 初始化,否则返回 ERROR_INVALID_PARAMETER 或 ERROR_NOT_SUPPORTED。常见错误是忽略返回值检查,或传入过低的 dwClientVersion(Win10建议用2,XP只支持1)。
关键步骤:
- 调用
WlanOpenHandle(2, nullptr, &dwNegotiatedVersion, &hClient)获取有效句柄 - 用
WlanEnumInterfaces(hClient, nullptr, &pInterfaceList)获取所有无线适配器 - 对每个
pInterfaceList->InterfaceInfo[i].InterfaceGuid调用WlanGetNetworkBssList才能拿到实际SSID
Linux下用iwlist扫描需注意权限与设备名硬编码风险
iwlist wlan0 scan 看似简单,但 wlan0 在不同机器上可能是 wlp2s0、enp0s20f0u1 甚至 mlan0(ARM嵌入式)。硬写设备名会导致程序在其他机器直接失败。
更可靠的做法:
- 用
ls /sys/class/net/*/wireless | cut -d/ -f5动态获取第一个无线接口名 - 执行
iwlist <iface> scan 2>/dev/null | grep -E 'ESSID|Signal'</iface>提取关键字段 - 注意:普通用户需将当前用户加入
netdev组,或用sudo setcap cap_net_raw+ep ./your_program授予能力,而非直接加sudo
macOS需通过CoreWLAN框架且无法绕过沙盒限制
系统策略禁止非App Store应用直接调用 CWInterface 的 scanForNetworksWithName:error:,会静默失败或抛出 kCWNoDataFromHardwareError。即使代码编译通过,运行时大概率拿不到结果。
可行路径只有两条:
- 打包为Mac App Store应用并开启“Access WiFi Information” entitlement
- 改用命令行工具
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s解析输出(需处理空格转义和信号强度单位) - 注意:
airport路径在macOS 13+已移至/usr/libexec/airport,旧路径失效
跨平台统一处理SSID字符串要警惕编码与空终止
Windows返回的 DOT11_SSID 是裸字节数组,长度由 uSSIDLength 字段决定,不是C字符串;Linux iwlist 输出可能含UTF-8中文SSID但混有控制字符;macOS airport 输出默认是UTF-8但字段对齐靠空格,容易误切。
安全做法:
- Windows:用
std::string(ssid.ucSSID, ssid.uSSIDLength)构造,不依赖\0 - Linux/macOS:对每行输出用正则匹配
ESSID:"([^"]*)"或^([^\s]+)\s+(-?\d+)\s+,避免按空格split - 显示前统一做trim和不可见字符过滤(如
\r、\t、零宽空格)
真正麻烦的不是怎么扫,而是不同系统对“同一个SSID”的表示差异——比如隐藏网络在Windows里仍返回名称但信号为0,在Linux里根本不出现在扫描结果中。这点必须在业务逻辑层显式区分处理。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











