GetAdaptersInfo和GetAdaptersAddresses函数可以获取到本地网卡的mac、IPV4地址、IPV6地址等各种信息。也可获取到有线网卡、环回网卡、隧道网、无线网卡等不同类型的网络信息。msdn推荐,在widows xp系统之后使用GetAdaptersAddresses函数。比如:使用GetAdaptersInfo() 获得本机网卡信息, 用在win8上有个问题, 蓝牙开启时读不到信息。
#include <string>
#include <WinSock2.h>
#include <windows.h>
#include <atlbase.h>
#include <Ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment(lib,"Ws2_32.lib") //inet_ntop
#pragma comment(lib,"Iphlpapi.lib") //GetAdaptersAddresses
int main(int argc, char * argv[])
{
ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS;//包括 IPV4 ,IPV6 网关
//flags |= GAA_FLAG_SKIP_DNS_SERVER; //不用返回DSN
//flags |= GAA_FLAG_SKIP_MULTICAST; //不用返回多播地址
//flags |= GAA_FLAG_SKIP_ANYCAST;//不用返回广播地址
ULONG family = AF_UNSPEC;//返回包括 IPV4 和 IPV6 地址
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
ULONG outBufLen = 0;
DWORD dwRetVal = 0;
PIP_ADAPTER_ADDRESSES pCurAddresses = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
IP_ADAPTER_PREFIX *pPrefix = NULL;
LPVOID lpMsgBuf = NULL;
outBufLen = 15000;
do
{
pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen);
if (pAddresses == NULL)
return 0;
dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
free(pAddresses);
pAddresses = NULL;
}
else
break;
} while (dwRetVal == ERROR_BUFFER_OVERFLOW);
USES_CONVERSION;
if (dwRetVal == NO_ERROR)
{
pCurAddresses = pAddresses;
while (pCurAddresses)
{
printf("Adapter name:%s Description::%s Friendly name:%s\n", pCurAddresses->AdapterName, T2A(pCurAddresses->Description), T2A(pCurAddresses->FriendlyName));
if (wcsstr(pCurAddresses->Description, _T("Bluetooth")) || wcsstr(pCurAddresses->Description, _T("bluetooth"))) //过滤蓝牙设备(一些蓝牙设备被当做以太网卡。)
{
pCurAddresses = pCurAddresses->Next;
continue;
}
if (pCurAddresses->PhysicalAddressLength != 0)
{
char szMac[1024] = { 0 };
sprintf_s(szMac, "%02X%02X%02X%02X%02X%02X", pCurAddresses->PhysicalAddress[0], pCurAddresses->PhysicalAddress[1],
pCurAddresses->PhysicalAddress[2], pCurAddresses->PhysicalAddress[3], pCurAddresses->PhysicalAddress[4], pCurAddresses->PhysicalAddress[5]);
printf("Adapter Mac:%s\n", szMac);
}
std::string strAapaterType = "";
switch (pCurAddresses->IfType) //类型,列举了几种
{
case MIB_IF_TYPE_ETHERNET:
strAapaterType = "以太网接口";
break;
case MIB_IF_TYPE_PPP:
strAapaterType = "PPP接口";
break;
case MIB_IF_TYPE_LOOPBACK:
strAapaterType = "软件回路接口";
break;
case MIB_IF_TYPE_SLIP:
strAapaterType = "ATM网络接口";
break;
case IF_TYPE_IEEE80211:
strAapaterType = "无线网络接口";
break;
}
printf("网卡类型:%s\n", strAapaterType.c_str());
pUnicast = pCurAddresses->FirstUnicastAddress;
int nIndex = 1;
while (pUnicast)//单播IP
{
char szIP[256] = { 0 };
if (AF_INET == pUnicast->Address.lpSockaddr->sa_family)// IPV4 地址,使用 IPV4 转换
{
inet_ntop(PF_INET, &((sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, szIP, sizeof(szIP));
}
else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family)// IPV6 地址,使用 IPV6 转换
{
inet_ntop(PF_INET6, &((sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, szIP, sizeof(szIP));
}
printf("单播 ip address index:%d ip:%s\n",nIndex, szIP);
pUnicast = pUnicast->Next;
nIndex++;
}
if (pCurAddresses->Dhcpv4Server.lpSockaddr)//IPV4 DHCP
{
char szDhcp[256] = { 0 };
if (AF_INET == pCurAddresses->Dhcpv4Server.lpSockaddr->sa_family)
{
inet_ntop(PF_INET, &((sockaddr_in*)pCurAddresses->Dhcpv4Server.lpSockaddr)->sin_addr, szDhcp, sizeof(szDhcp));
}
else if (AF_INET6 == pCurAddresses->Dhcpv4Server.lpSockaddr->sa_family)
{
inet_ntop(PF_INET6, &((sockaddr_in6*)pCurAddresses->Dhcpv4Server.lpSockaddr)->sin6_addr, szDhcp, sizeof(szDhcp));
}
printf("Dhcpv4Server DHCP地址:%s\n", szDhcp);
}
nIndex = 1;
pDnServer = pCurAddresses->FirstDnsServerAddress;
while (pDnServer)//DNS
{
char szDNS[256] = { 0 };
if (AF_INET == pDnServer->Address.lpSockaddr->sa_family)
{
inet_ntop(PF_INET, &((sockaddr_in*)pDnServer->Address.lpSockaddr)->sin_addr, szDNS, sizeof(szDNS));
}
else if (AF_INET6 == pDnServer->Address.lpSockaddr->sa_family)
{
inet_ntop(PF_INET6, &((sockaddr_in6*)pDnServer->Address.lpSockaddr)->sin6_addr, szDNS, sizeof(szDNS));
}
printf("DNS address index:%d address:%s\n", nIndex, szDNS);
pDnServer = pDnServer->Next;
nIndex++;
}
// MTU
printf("MTU:%u\n", pCurAddresses->Mtu);
//发送速率
printf("send speed:%lldbit/s\n", pCurAddresses->TransmitLinkSpeed);
//接收速率
printf("recv speed:%lldbit/s\n", pCurAddresses->ReceiveLinkSpeed);
PIP_ADAPTER_GATEWAY_ADDRESS_LH pGateway = pCurAddresses->FirstGatewayAddress;
nIndex = 1;
while (pGateway)//网关
{
char szGateway[256] = { 0 };
if (AF_INET == pGateway->Address.lpSockaddr->sa_family)
{
inet_ntop(PF_INET, &((sockaddr_in*)pGateway->Address.lpSockaddr)->sin_addr, szGateway, sizeof(szGateway));
}
else if (AF_INET6 == pGateway->Address.lpSockaddr->sa_family)
{
inet_ntop(PF_INET6, &((sockaddr_in6*)pGateway->Address.lpSockaddr)->sin6_addr, szGateway, sizeof(szGateway));
}
printf("gateway index:%d address:%s\n", nIndex, szGateway);
pGateway = pGateway->Next;
nIndex++;
}
if (pCurAddresses->Dhcpv6Server.lpSockaddr)//IPV6 DHCP
{
char szDhcp[256] = { 0 };
if (AF_INET == pCurAddresses->Dhcpv6Server.lpSockaddr->sa_family)
{
inet_ntop(PF_INET, &((sockaddr_in*)pCurAddresses->Dhcpv6Server.lpSockaddr)->sin_addr, szDhcp, sizeof(szDhcp));
}
else if (AF_INET6 == pCurAddresses->Dhcpv6Server.lpSockaddr->sa_family)
{
inet_ntop(PF_INET6, &((sockaddr_in6*)pCurAddresses->Dhcpv6Server.lpSockaddr)->sin6_addr, szDhcp, sizeof(szDhcp));
}
printf("Dhcpv6Server DHCP地址:%s\n", szDhcp);
}
pCurAddresses = pCurAddresses->Next;
}
}
else
{
printf("Call to GetAdaptersAddresses failed with error: %d\n", dwRetVal);
if (dwRetVal == ERROR_NO_DATA)
{
printf("No addresses were found for the requested parameters\n");
}
else
{
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)& lpMsgBuf, 0, NULL))
{
printf("Error: %s\n", (char *)lpMsgBuf);
LocalFree(lpMsgBuf);
if (pAddresses)
{
free(pAddresses);
pAddresses = NULL;
}
exit(1);
}
}
}
if (pAddresses)
{
free(pAddresses);
pAddresses = NULL;
}
return 0;
}
注意:
1、error C2011: “sockaddr”:“struct”类型重定义错误,彻底解决windows.h和winsock2.h重定义。
解决办法:
方法1,#include <Windows.h>放在#include <WinSock2.h>后面。
方法2,在宏定义中加入以下这句话
WIN32_LEAN_AND_MEAN