C++ Linux获取MAC地址在同一台计算机上返回不同的值

标签 c++ linux

我总结了以下代码以获取计算机 MAC 地址 (Linux Ubuntu) 并使用自定义十六进制字符串打印它:

#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <stdexcept>

#include <unistd.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/ioctl.h>


std::string convertToHex(std::string str)
{
    std::stringstream outText;

    for(unsigned int i = 0; i < str.size(); i++ )
    {
        outText << std::hex << std::setw(2) << std::setfill('0') << (0xFF & static_cast<char>(str[i]));

        if (i != (str.size() - 1))
            outText << ":";
    }

    return outText.str();
}

std::string getMacId()
{
    struct ifreq ifr;
    struct ifreq *IFR;
    struct ifconf ifc;
    char buf[1024];
    int s, i;
    std::string macAddr("");

    s = socket(AF_INET, SOCK_DGRAM, 0);

    if (s==-1)
    {
        return "";
    }

    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    ioctl(s, SIOCGIFCONF, &ifc);

    IFR = ifc.ifc_req;
    int ok = 0;
    for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++)
    {

        strcpy(ifr.ifr_name, IFR->ifr_name);
        if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0)
        {
            if (! (ifr.ifr_flags & IFF_LOOPBACK))
            {
                if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0)
                {
                    ok = 1;
                    break;
                }
            }
        }
    }

    close(s);

    std::stringstream data;

    for (auto &c : ifr.ifr_addr.sa_data)
        data << c;

    std::string ret = data.str();

    std::cout << ret << std::endl;

    return ret;
}


void showMacId()
{
    std::string mac = getMacId();

    std::string hexmac = convertToHex(mac);

    std::cout << hexmac << std::endl;
}

int main()
{
    std::cout << "Pass1: " << std::endl;
    showMacId();

    std::cout << "Pass2: " << std::endl;
    showMacId();

    std::cout << "Pass3: " << std::endl;
    showMacId();

    std::cout << "Pass4: " << std::endl;
    showMacId();
}

问题是每次读取时我都会得到不同的输出。这是运行程序的结果:

Pass1: 
.)� W�� 
2e:02:00:00:04:29:80:20:57:82:42:08:80:20
Pass2: 
p�ЕĿ�wq���Ŀ
70:b7:d0:95:c4:bf:aa:77:71:b7:80:95:c4:bf
Pass3: 
p�ЕĿ�wq���Ŀ
70:b7:d0:95:c4:bf:aa:77:71:b7:80:95:c4:bf
Pass4: 
p�ЕĿ�wq���Ŀ
70:b7:d0:95:c4:bf:aa:77:71:b7:80:95:c4:bf

如果我再次运行程序,我会得到不同的结果:

Pass1: 
.)� W�� 
2e:02:00:00:04:29:80:20:57:82:42:08:80:20
Pass2: 
q��
���wr�P
��
71:b7:a0:0a:93:bf:aa:77:72:b7:50:0a:93:bf
Pass3: 
q��
���wr�P
��
71:b7:a0:0a:93:bf:aa:77:72:b7:50:0a:93:bf
Pass4: 
q��
���wr�P
��
71:b7:a0:0a:93:bf:aa:77:72:b7:50:0a:93:bf

那么,我做错了什么?

最佳答案

sizeof(buf)看起来很危险。改为使用 1024;我不确定你不要求 sizeof(char*)这样。

必须检查

    ioctl(s, SIOCGIFCONF, &ifc);

不返回-1!

总而言之,这似乎是一种非常古老的获取 MAC 地址的方法。

你为什么不直接阅读 /sys/class/net/<devicename>/address ?我几乎可以依赖 sysfs 在我遇到的任何 linux 系统上,它是故障安全、清晰、可移植的事情。要查找您的设备,只需列出 /sys/calls/net/目录。

编辑 我被要求举个例子;我真的不知道该怎么做,看起来很简单:

#include <iostream>
#include <fstream>


int main (int argc, char** argv)
{

    std::ifstream inp ("/sys/class/net/enp0s25/address", std::ifstream::in);
    for(int bytecounter = 0; bytecounter < 6; bytecounter++)
    {   
        unsigned int byte;
        inp >>std::hex >> byte;
        inp.get(); //drop the :
        std::cout <<byte;
        if(bytecounter < 5)
            std::cout << ":";
    }   

    inp.close();

    return 0;
}

关于C++ Linux获取MAC地址在同一台计算机上返回不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30684590/

相关文章:

c++ - 为什么我的可变参数宏不能正确接受任何参数?

linux -/var/run/screen/... 上的 "p"权限是什么?

linux - 如何从后台进程重定向日志

linux - Bash:使用 ls 、 awk 和 grep 列出文件大小

c++ - Mingw libgcc_s_sjlj-1.dll 丢失

c++ - Visual C++ 中 DLL 的 DLL 导出和接口(interface)

c++ - 强制编译时 constexpr

linux - 如何获取ELF文件的A值?

MySQL 服务器正在运行但正在获取 "Can' t Connect”

c++ - 是否有标准库函数可以反转 STL 堆栈?