我将以下代码包装起来以获取计算机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
那么,我在这里做错了什么?
答案 0 :(得分:2)
sizeof(buf)
看起来很危险。改用1024;我并不完全确定你不会以这种方式要求sizeof(char*)
。
您必须检查
ioctl(s, SIOCGIFCONF, &ifc);
不会返回-1!
总而言之,这似乎是一种非常老派的获取MAC地址的方法。
你为什么不阅读/sys/class/net/<devicename>/address
?在我遇到的任何Linux系统上,我几乎都可以依赖sysfs,而且它是故障安全,清晰,便携的事情。要查找您的设备,只需列出/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;
}
答案 1 :(得分:0)
我不确定为什么&#34; MAC&#34;您正在打印的地址很长(通常它们是48位长),但我想您的问题是您没有用零初始化结构和数组。
这应该有所帮助(假设你使用C ++ 11):
struct ifreq ifr = {0};
struct ifconf ifc = {0};
char buf[1024] = {0};