前言   这是一个Qt项目,需求是显示连接网卡的ip,过滤掉断开的和虚拟网卡等。本来想直接使用Qt提供的QNetworkConfigurationManager,但是在虚拟机里面这个接口某些情况无法检测到网卡配置,最后还是采用Windows API稳妥方案解决。WinAPI封装的com接口里面可以使用wmi nic查询网卡硬件相关的信息,但是这个接口主要是提供硬件信息,ip是个保留项,里面没有填充数据。所以还是直接使用<iphlpapi.h>里面接口。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) #define WORKING_BUFFER_SIZE 15000 #define MAX_TRIES 3 void queryNetcardIP{ DWORD dwRetVal = 0 ; unsigned int i = 0 ; ULONG flags = GAA_FLAG_INCLUDE_PREFIX; ULONG family = AF_UNSPEC; PIP_ADAPTER_ADDRESSES pAddresses = NULL ; ULONG outBufLen = 0 ; ULONG Iterations = 0 ; PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL ; IP_ADAPTER_PREFIX *pPrefix = NULL ; family = AF_INET; outBufLen = WORKING_BUFFER_SIZE; do { pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC (outBufLen); if (pAddresses == NULL ) { return ; } dwRetVal = GetAdaptersAddresses (family, flags, NULL , pAddresses, &outBufLen); if (dwRetVal == ERROR_BUFFER_OVERFLOW) { FREE (pAddresses); pAddresses = NULL ; } else { break ; } Iterations++; } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); if (dwRetVal == NO_ERROR) { pCurrAddresses = pAddresses; QStringList list; while (pCurrAddresses) { QString description = QString::fromWCharArray (pCurrAddresses->Description); if (description.contains ("VirtualBox" , Qt::CaseInsensitive) || description.contains ("VMware" , Qt::CaseInsensitive) || (pCurrAddresses->OperStatus == 2 ) || (pCurrAddresses->IfType == IF_TYPE_SOFTWARE_LOOPBACK)) ) { pCurrAddresses = pCurrAddresses->Next; continue ; } pPrefix = pCurrAddresses->FirstPrefix; if (pPrefix) { for (i = 0 ; pPrefix != NULL ; i++) { if (i == 1 ) { sockaddr_in *address = (sockaddr_in *) pPrefix->Address.lpSockaddr; list.append (inet_ntoa (address->sin_addr)); break ; } pPrefix = pPrefix->Next; } } pCurrAddresses = pCurrAddresses->Next; } qInfo () << list; } if (pAddresses) { FREE (pAddresses); } }
其实PIP_ADAPTER_ADDRESSES这个结构体里面还有很多其他重要信息,比如网卡速率,网卡类型等。