【工具类】本机获取socket对应的IP地址及MAC地址

本文介绍了一个使用C++实现的函数,该函数能够通过指定的IP地址获取其对应的MAC地址。代码中利用了winsock2.h、Iptypes.h和IPHlpApi.h等头文件,并通过GetAdaptersInfo函数遍历网络适配器信息,从而找到与输入IP匹配的MAC地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <winsock2.h>
#include <Iptypes.h>
#include <IPHlpApi.h>

#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

BOOL GetMacAddressByIP(const char* v_szIPAddress, char* v_szMACAddress)
{
	BOOL bSuccess = FALSE;
	//获取Mac地址和IP地址
	PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();  //PIP_ADAPTER_INFO结构体指针存储本机网卡信息
	PIP_ADAPTER_INFO pIpAdapterInfoTemp = NULL;
	unsigned long stSize = sizeof(IP_ADAPTER_INFO);
	int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
	//如果函数返回的是ERROR_BUFFER_OVERFLOW,则GetAdaptersInfo参数传递的内存空间不够,传出stSize表示需要的空间大小
	if (ERROR_BUFFER_OVERFLOW == nRel)
	{
		//释放原来的内存空间
		delete pIpAdapterInfo;
		//重新申请内存空间用来存储所有网卡信息
		pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
		//再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
		nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
	}

	pIpAdapterInfoTemp = pIpAdapterInfo;
	if (nRel == ERROR_SUCCESS) //调用成功则输出网卡信息,可能存在多张网卡
	{
		while (pIpAdapterInfoTemp)//输出每张网卡的数据
		{
			IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfoTemp->IpAddressList);
			do //输出一张网卡上所有的IP
			{
				if ((NULL != pIpAddrString->IpAddress.String) && !strstr(pIpAddrString->IpAddress.String, "0.0.0.0"))
				{
					if (0 == strcmp(v_szIPAddress, pIpAddrString->IpAddress.String)) //判断此网卡是否有目标IP
					{
						sprintf_s(v_szMACAddress, 20, "%02x:%02x:%02x:%02x:%02x:%02x", 
							pIpAdapterInfoTemp->Address[0],
							pIpAdapterInfoTemp->Address[1],
							pIpAdapterInfoTemp->Address[2], 
							pIpAdapterInfoTemp->Address[3], 
							pIpAdapterInfoTemp->Address[4],
							pIpAdapterInfoTemp->Address[5]);

						bSuccess = TRUE;
						goto END;
					}
				}

				pIpAddrString = pIpAddrString->Next;//一张网卡上的下一个IP地址
			} while (pIpAddrString);

			pIpAdapterInfoTemp = pIpAdapterInfoTemp->Next;//下一张网卡,一台主机可以有多张网卡
		}
	}

END:
	delete[]pIpAdapterInfo;
	pIpAdapterInfo = NULL;

	return bSuccess;
}

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsaData;
	if (WSAStartup(0x202, &wsaData) == 0)
	{
		SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
		if (SOCKET_ERROR != sock)
		{
			SOCKADDR_IN siServerAddr;
			memset(&siServerAddr, 0, sizeof(SOCKADDR_IN));
			siServerAddr.sin_family = AF_INET;
			siServerAddr.sin_port = htons(20081);
			siServerAddr.sin_addr.s_addr = inet_addr("192.168.1.2");
			if (SOCKET_ERROR != connect(sock, (PSOCKADDR)&siServerAddr, sizeof(siServerAddr)))
			{
				//获取此socket使用的IP地址
				SOCKADDR_IN siClientAddr;
				int iLen = sizeof(SOCKADDR_IN);
				memset(&siClientAddr, 0, iLen);
				char szClientIP[30] = { 0 };
				int iRet = getsockname(sock, (PSOCKADDR)&siClientAddr, &iLen);
				if (0 == iRet)
				{
					strcpy_s(szClientIP, inet_ntoa(siClientAddr.sin_addr));
					printf("Client Sock IP:%s PORT:%d\n", szClientIP, ntohs(siClientAddr.sin_port));
				}

				//拿到此IP对应的网卡MAC地址
				char szMACAddress[20] = { 0 };
				if (GetMacAddressByIP(szClientIP, szMACAddress))
				{
					printf("IP:%s---->MAC:%s\n", szClientIP, szMACAddress);
				}
				else
				{
					printf("GetMacAddressByIP Failed.\n");
				}
			}

			closesocket(sock);
		}

		WSACleanup();
	}

	system("pause");
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值