windows有虚拟网卡或多个网卡的情况下,很难判断本机IP到底用的哪一个网卡上的IP,也难以区分虚拟网卡和物理网上。
这里我们使用windows的函数GetBestInterface(destIP,index), 系统会给一个到指定IP地址的最适合的网卡的序列号,通过这个序列号再遍历各个网卡就可以得到当前系统所用的网卡是哪一个,如果只有一个物理网卡,也默认使用此物理网卡。
使用此方法需要注意, 如果电脑网络未连接,GetBestInterface会返回失败。只有在联网状态并下才会成功。
对一些需要联网才能运行的程序来说,用这种方法是没有问题的。
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
int main()
{
IPAddr add = 0x08080808;//用8.8.8.8这个IP
DWORD index;
auto ret = GetBestInterface(add, &index);
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
UINT i;
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == NULL) {
printf("Error allocating memory needed to call GetAdaptersinfo\n");
return 1;
}
// Make an initial call to GetAdaptersInfo to get
// the necessary size into the ulOutBufLen variable
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
if (pAdapterInfo == NULL) {
printf("Error allocating memory needed to call GetAdaptersinfo\n");
return 1;
}
}
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
while (pAdapter) {
if (pAdapter->Index != index)
continue;
printf("\tComboIndex: \t5d\n", pAdapter->ComboIndex);
printf("\tAdapter Name: \t%s\n", pAdapter->AdapterName);
printf("\tAdapter Desc: \t%s\n", pAdapter->Description);
printf("\tAdapter Addr: \t");
for (i = 0; i < pAdapter->AddressLength; i++) {
if (i == (pAdapter->AddressLength - 1))
printf("%.2X\n", (int)pAdapter->Address[i]);
else
printf("%.2X-", (int)pAdapter->Address[i]);
}
printf("\tIndex: \t%d\n", pAdapter->Index);
printf("\tIP Address: \t%s\n",pAdapter->IpAddressList.IpAddress.String);
printf("\tIP Mask: \t%s\n", pAdapter->IpAddressList.IpMask.String);
printf("\tGateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);
printf("\t***\n");
pAdapter = pAdapter->Next;
printf("\n");
}
}
else {
printf("GetAdaptersInfo failed with error: %d\n", dwRetVal);
}
if (pAdapterInfo)
free(pAdapterInfo);
getchar();
return 0;
}