【工具類】本機獲取socket對應的IP地址及MAC地址

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章