一种windows获取本机IPV4和IPv6的方法
代码测试环境
windows11
- 编译器
MSVC
获取思路
- 先遍历
本机物理网卡
, 再遍历每块网卡
上所有的IP
使用效果
-
ipv4
-
ipv6
说明
说明
说明
- 之前有篇文章,也描述了windows获取本机IP的方法,实践测试发现并不是特别准确。文章地址:https://www.cnblogs.com/pandamohist/p/13756480.html
源代码
#pragma once
#include <WinSock2.h>
#include <iphlpapi.h>
#include <windows.h>
#include <WS2tcpip.h>
#include <set>
#include <string>
#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "ws2_32.lib")
/// ----------------------------------------------
/// @brief: windows本机IP获取助手
/// ----------------------------------------------
class WinNetInterfaceHelper
{
public:
WinNetInterfaceHelper()
{
WSAData data;
int err = WSAStartup(MAKEWORD(2, 2), &data);
if (0 != err)
{
/// 出现错误
}
}
virtual~ WinNetInterfaceHelper()
{
WSACleanup();
}
/// ----------------------------------------------
/// @brief: 获取本机IPV4
/// ----------------------------------------------
std::set<std::string> ipv4()
{
return netInterfaceSet(AF_INET, INET_ADDRSTRLEN);
}
/// ----------------------------------------------
/// @brief: 获取本机IPV6
/// ----------------------------------------------
std::set<std::string> ipv6()
{
return netInterfaceSet(AF_INET6, INET6_ADDRSTRLEN);
}
private:
std::set<std::string> netInterfaceSet(int family, int addressLen)
{
std::set<std::string> retValue;
ULONG outBufferLen = sizeof(IP_ADAPTER_ADDRESSES);
PIP_ADAPTER_ADDRESSES paddress = (PIP_ADAPTER_ADDRESSES)malloc(outBufferLen);
/// 第一次获取缓存的大小
DWORD dwRetVal = GetAdaptersAddresses(family, 0, NULL, paddress, &outBufferLen);
free(paddress);
paddress = (PIP_ADAPTER_ADDRESSES)malloc(outBufferLen);
memset(paddress, 0, outBufferLen);
dwRetVal = GetAdaptersAddresses(family, 0, NULL, paddress, &outBufferLen);
if (dwRetVal != NO_ERROR)
{
free(paddress);
paddress = nullptr;
return retValue;
}
/// 逐一遍历网卡中的IP
for (PIP_ADAPTER_ADDRESSES curAddress = paddress; curAddress != nullptr; curAddress = curAddress->Next)
{
if (NULL == curAddress->FirstUnicastAddress)
{
continue;
}
// 遍历IP地址列表
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = curAddress->FirstUnicastAddress;
while (pUnicast)
{
sockaddr_in* sockaddr_ipv4 = (sockaddr_in*)pUnicast->Address.lpSockaddr;
if (sockaddr_ipv4->sin_family == family)
{
char ipAddrStr[INET6_ADDRSTRLEN] = { 0 };
inet_ntop(family, &(sockaddr_ipv4->sin_addr), ipAddrStr, addressLen);
std::string tmpIP(ipAddrStr);
retValue.insert(tmpIP);
}
pUnicast = pUnicast->Next;
}
}
free(paddress);
return retValue;
}
};