一种windows获取本机IPV4和IPv6的方法

代码测试环境

  • windows11
  • 编译器 MSVC

获取思路

  • 先遍历本机物理网卡, 再遍历每块网卡上所有的IP

使用效果

  • ipv4

  • ipv6

说明

说明

说明

源代码

#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;

	}
};
posted @ 2024-11-06 20:18  mohist  阅读(4)  评论(0编辑  收藏  举报