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下:

 

posted @ 2023-05-10 11:28  xcywt  阅读(381)  评论(0编辑  收藏  举报
作者:xcywt
出处:https://www.cnblogs.com/xcywt//
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。