前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++如何获取网卡地址(跨平台)

C++如何获取网卡地址(跨平台)

作者头像
xcywt
发布2023-05-23 10:05:50
1.1K0
发布2023-05-23 10:05:50
举报
文章被收录于专栏:xcywtxcywt

需求:

  获取电脑网卡的硬件地址。就是Linux下运行ifconfig出来的硬件地址。直接上代码:  

windows下运行 ipconfig /all  显示的物理地址。

头文件:

GetMacAddrFunc.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
// ... 要包含头文件 ...

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求:
  • 头文件:
  • 源码:
  • 测试代码:
  • 结果:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档