如何获取Windows系统当前已连接的网络适配器信息?
查询Windows当前已连接Wi-Fi的适配器信息(适配mDNS场景)
问题描述
我需要查询Windows系统中当前已连接的Wi-Fi适配器的信息(包括可用单播/多播状态、是否为Wi-Fi、适配器名称等),这里的“已连接”指的是Windows Wi-Fi设置里显示的当前活跃Wi-Fi连接(和网络领域的通用定义可能有区别)。哪怕只拿到接口索引也行,因为用GetAdaptersAddresses()这类函数能轻松获取其他大部分信息。
补充背景(X/Y问题说明):我正在做学术研究用的mDNS客户端(我知道Windows自带mDNS API),希望只在当前Wi-Fi网络上进行广播和接收(我知道需要用setsockopt设置IP_ADD_SOURCE_MEMBERSHIP标志),同时得确定mDNS响应里要返回哪个IP地址。我已经能设置IP_ADD_MEMBERSHIP,但还是需要明确返回的IP,而且单网络操作从逻辑上更简单。
解决方案
方法1:用WLAN API定位当前活跃Wi-Fi接口
Windows WLAN API可以精准定位当前连接的Wi-Fi适配器,步骤如下:
- 调用
WlanOpenHandle()初始化WLAN句柄 - 通过
WlanEnumInterfaces()枚举所有Wi-Fi接口 - 对每个接口调用
WlanGetAvailableNetworkList(),筛选出包含WLAN_AVAILABLE_NETWORK_CONNECTED标志的网络,拿到对应接口的GUID - 用该GUID匹配
GetAdaptersAddresses()的结果,提取接口索引、IP地址等关键信息
核心C++代码片段:
#include <wlanapi.h> #include <iphlpapi.h> #include <guiddef.h> #pragma comment(lib, "wlanapi.lib") #pragma comment(lib, "iphlpapi.lib") int main() { HANDLE hWlan; DWORD dwVersion; // 打开WLAN句柄 if (WlanOpenHandle(2, NULL, &dwVersion, &hWlan) != ERROR_SUCCESS) { return 1; } PWLAN_INTERFACE_INFO_LIST pIfList = NULL; // 枚举所有Wi-Fi接口 if (WlanEnumInterfaces(hWlan, NULL, &pIfList) != ERROR_SUCCESS) { WlanCloseHandle(hWlan, NULL); return 1; } for (DWORD i = 0; i < pIfList->dwNumberOfItems; i++) { PWLAN_INTERFACE_INFO pIfInfo = &pIfList->InterfaceInfo[i]; PWLAN_AVAILABLE_NETWORK_LIST pNetList = NULL; // 获取当前接口的可用网络列表 if (WlanGetAvailableNetworkList(hWlan, &pIfInfo->InterfaceGuid, 0, NULL, &pNetList) != ERROR_SUCCESS) { continue; } for (DWORD j = 0; j < pNetList->dwNumberOfItems; j++) { PWLAN_AVAILABLE_NETWORK pNet = &pNetList->Network[j]; // 筛选已连接的Wi-Fi网络 if (pNet->dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) { // 匹配GetAdaptersAddresses结果,获取接口索引和IP IP_ADAPTER_ADDRESSES* pAdapterAddr = NULL; ULONG bufLen = 0; GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &bufLen); pAdapterAddr = (IP_ADAPTER_ADDRESSES*)malloc(bufLen); if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddr, &bufLen) == ERROR_SUCCESS) { IP_ADAPTER_ADDRESSES* currAdapter = pAdapterAddr; while (currAdapter) { if (IsEqualGUID(&currAdapter->AdapterGuid, &pIfInfo->InterfaceGuid)) { // 拿到目标接口索引 DWORD ifIndex = currAdapter->IfIndex; // 遍历获取单播IP地址 IP_ADAPTER_UNICAST_ADDRESS* unicastAddr = currAdapter->FirstUnicastAddress; while (unicastAddr) { // 处理IP地址(可转换为字符串) unicastAddr = unicastAddr->Next; } break; } currAdapter = currAdapter->Next; } } free(pAdapterAddr); } } WlanFreeMemory(pNetList); } WlanFreeMemory(pIfList); WlanCloseHandle(hWlan, NULL); return 0; }
方法2:用Network List Manager API快速获取活跃接口
如果不需要深入Wi-Fi细节,Network List Manager API更简洁:
- 通过
INetworkListManager枚举所有网络,筛选CONNECTED状态的实例 - 从
INetwork关联到INetworkInterface,直接获取接口类型(判断是否为Wi-Fi)、ID、IP地址等信息
mDNS场景适配说明
拿到目标接口信息后:
- 设置
IP_ADD_SOURCE_MEMBERSHIP时,将ip_mreqn.imr_ifindex设为目标接口索引,组地址指定mDNS标准地址(IPv4为224.0.0.251,IPv6为ff02::fb) - mDNS响应优先返回该接口的IPv4单播地址;若需支持IPv6,选择链路本地类型的IPv6地址
- 提前通过
GetAdaptersAddresses()确认接口支持多播(IP_ADAPTER_ADDRESSES.Flags包含IP_ADAPTER_MULTICAST)
内容的提问来源于stack exchange,提问作者Tom Hickson
相关产品推荐
相关产品推荐

