C++如何获取网卡地址(跨平台)
需求:
获取电脑网卡的硬件地址。就是Linux下运行ifconfig出来的硬件地址。直接上代码:
windows下运行 ipconfig /all 显示的物理地址。
头文件:
GetMacAddrFunc.h
#ifndef __DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__ #define __DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__ #include <vector> #include <string> namespace DDRGadgets { // 获取机器的MAC地址 std::vector<std::string> GetMacAddr(); } #endif // __DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__
源码:
windows下要定义宏:_WIN32和_WIN64
linux下要定义宏:__linux__
GetMacAddrFunc.cpp
#include "GetMacAddrFunc.h" #include <string> #if defined(_WIN32) || defined(_WIN64) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #include <iphlpapi.h> #pragma comment(lib, "iphlpapi.lib") #elif defined(__linux__) #include <ifaddrs.h> #include <netpacket/packet.h> #endif namespace DDRGadgets { std::vector<std::string> GetMacAddr() { std::vector<std::string> vec; std::string str; #if defined(_WIN32) || defined(_WIN64) ULONG outBufLen = 0; DWORD dwRetVal = ::GetAdaptersInfo(0, &outBufLen); if (ERROR_BUFFER_OVERFLOW != dwRetVal) { return vec; } outBufLen = ((outBufLen + sizeof(IP_ADAPTER_INFO) - 1) / sizeof(IP_ADAPTER_INFO)); IP_ADAPTER_INFO *AdapterInfos = new IP_ADAPTER_INFO[outBufLen]; outBufLen *= sizeof(IP_ADAPTER_INFO); dwRetVal = ::GetAdaptersInfo(AdapterInfos, &outBufLen); if (NO_ERROR != dwRetVal) { return vec; } outBufLen /= sizeof(IP_ADAPTER_INFO); for (int jj = 0; jj < outBufLen; ++jj) { str.resize(3 * AdapterInfos[jj].AddressLength - 1); char *pCur = &str[0]; for (int i = 0; i < (int)AdapterInfos[jj].AddressLength; ++i) { pCur += snprintf(pCur, 3, "%02x", (int)AdapterInfos[jj].Address[i]); if (i + 1 < (int)AdapterInfos[jj].AddressLength) { *(pCur++) = ':'; } } vec.push_back(str); } delete[] AdapterInfos; #else struct ifaddrs *pIfAddr; if (-1 == getifaddrs(&pIfAddr)) { return vec; } struct ifaddrs *pIFA = pIfAddr; for (; pIFA; pIFA = pIFA->ifa_next) { if (!(pIFA->ifa_addr) || AF_PACKET != pIFA->ifa_addr->sa_family) { continue; } auto paddr = (sockaddr_ll*)pIFA->ifa_addr; bool bNullAddr = true; for (int i = 0; i < (int)paddr->sll_halen; ++i) { if (0 != (int)paddr->sll_addr[i]) { bNullAddr = false; break; } } if (bNullAddr) { continue; } str.resize((int)paddr->sll_halen * 3 - 1); char *pCur = &str[0]; for (int i = 0; i < (int)paddr->sll_halen; ++i) { pCur += snprintf(pCur, 3, "%02x", (int)paddr->sll_addr[i]); if (i + 1 < (int)paddr->sll_halen) { *(pCur++) = ':'; } } vec.push_back(str); } freeifaddrs(pIfAddr); #endif return vec; } }
测试代码:
macTest.cpp
// ... 要包含头文件 ... void test20230510() { auto vecMacAddr = DDRGadgets::GetMacAddr(); int i = 0; for (auto iii : vecMacAddr) { i++; printf("MacAddr%d:%s\n", i, iii.c_str()); } } int main() { std::cout << "Mac Test ...\n"; test20230510(); return 0; }
结果:
注意编译时要带上 -std=C++11
windows下: