![Visual C++ 2017网络编程实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/473/34061473/b_34061473.jpg)
上QQ阅读APP看书,第一时间看更新
2.3 获取本机物理网卡地址信息
网卡地址也就是MAC地址,是一个用来确认网上设备位置的地址。它的长度是48比特(6字节),由16进制的数字组成,分为前24位和后24位。在Windows下,单击【开始】按钮,选择【运行】菜单,输入“cmd”,然后输入“ipconfig /all”(或者输入“ipconfig-all”)就可以看到网卡地址了,如图2-5所示。
![](https://epubservercos.yuewen.com/F84FA5/18225432201803906/epubprivate/OEBPS/Images/Figure-P53_4227.jpg?sign=1739368774-7zKdWs57glc6wQF03jD1b5ciCHqramLl-0-00d88f0d6078bc807eeb7734cf65679c)
图2-5
获取网卡MAC地址的方法很多,如Netbios、SNMP、GetAdaptersInfo等。经过测试发现:Netbios方法在网线拔出的情况下获取不到MAC;而SNMP方法有时会获取多个重复的网卡的MAC;还是GetAdaptersInfo方法比较好,即使在网线拔出的情况下也可以获取MAC,而且很准确,不会重复获取网卡。
GetAdaptersInfo方法也不是十全十美的,也存在一些问题:
·如何区分物理网卡和虚拟网卡。
·如何区分无线网卡和有线网卡。
·“禁用”的网卡获取不到。
关于问题1和问题2,笔者的处理办法是:
·区分物理网卡和虚拟网卡:pAdapter->Description中包含"PCI"的是物理网卡。(试了3台机器可以。)
·区分无线网卡和有线网卡:pAdapter->Type为71的是无线网卡。(试了2个无线网卡可以。)
这些都是笔者的心血啊!希望大家不要再走弯路。关于函数GetAdaptersInfo,上面已经介绍过了,这里不再赘述。
【例2.3】获取本机物理网卡的地址信息
(1)新建一个控制台工程test。
(2)在test.cpp中输入如下代码:
#include "stdafx.h" #include <atlbase.h> #include <atlconv.h> #include "iphlpapi.h" #pragma comment ( lib, "Iphlpapi.lib") int main(int argc, char* argv[]) { PIP_ADAPTER_INFO pAdapterInfo; PIP_ADAPTER_INFO pAdapter = NULL; DWORD dwRetVal = 0; pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO)); ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS) { GlobalFree(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen); } if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { pAdapter = pAdapterInfo; while (pAdapter) { // pAdapter->Description中包含"PCI"的为物理网卡;pAdapter->Type是71的为无线网卡 if (strstr(pAdapter->Description, "PCI") > 0 || pAdapter->Type == 71) { printf("------------------------------\n"); printf("AdapterName: \t%s\n", pAdapter->AdapterName); printf("AdapterDesc: \t%s\n", pAdapter->Description); printf("AdapterAddr: \t"); for (UINT i = 0; i <pAdapter->AddressLength; i++) { printf("%X%c", pAdapter->Address[i], i == pAdapter->AddressLength - 1 ? '\n' : '-'); } printf("AdapterType: \t%d\n", pAdapter->Type); printf("IPAddress: \t%s\n", pAdapter->IpAddressList.IpAddress.String); printf("IPMask: \t%s\n", pAdapter->IpAddressList.IpMask.String); } pAdapter = pAdapter->Next; } } else { printf("Callto GetAdaptersInfo failed.\n"); } return 0; }
(3)保存工程并运行,结果如图2-6所示。
![](https://epubservercos.yuewen.com/F84FA5/18225432201803906/epubprivate/OEBPS/Images/Figure-P55_4556.jpg?sign=1739368774-gg54ozzHHuidjEFFwaSZNQnNQ5PR5Lqy-0-4656953c5ffe2cf2fa43425d96ba553a)
图2-6