问题描述
我正在尝试解析并显示我正在制作的许可程序的机器的 MAC 地址,但仅显示具有有效 IP 地址的那些。我已经获得了 IP/MAC,但我无法看到哪个有效,哪个无效。
这是我的代码:
void FormSerial::PopCB(QStringList CB){
for (int i = 0; i<CB.size(); i++){
if(CB.at(i) == "0.0.0.0"){
Log("verdadero " + CB.at(i+1));
widget.Mac_ComboBox->addItem(CB.at(i+1));
}else{
Log("Falso " + CB.at(i));
}
}
}
如果我这样做,它会向我显示那些没有有效 IP 地址的人,但我只想要那些拥有有效 IP 地址的人。如果我将 ==
中的 !=
更改为 if
,我将一无所获。
我有这样的数据:
CB = "0.0.0.0","42:45:65:25:89:45","196.568.68.49","45:98:75:85:15:85"
有什么想法吗?
解决方法
试试这个:
void FormSerial::PopCB(const QStringList &CB){
for (int i = 0; i < CB.size(); i += 2){
if (CB.at(i) != "0.0.0.0"){
const QString &mac = CB.at(i+1);
Log("verdadero " + mac);
widget.Mac_ComboBox->addItem(mac);
}
}
}
请注意,此代码仅处理 IPv4 IP 地址,但机器也可以拥有 IPv6 IP。所以你可能需要更新循环来处理它,例如:
if (ip != "0.0.0.0" && ip != "0000:0000:0000:0000:0000:0000:0000:0000"){
请注意,IPv6 IP 比 IPv4 更难解析,因为它们具有 many different possible representations,因此您最好使用知道如何解析 IP 地址字符串的 API/库,例如 inet_pton()
或 getaddrinfo()
,例如:
bool isValidIPv4(const QString &ip)
{
in_addr addr;
return (inet_pton(AF_INET,ip.c_str(),&addr) == 1)
&& (addr.s_addr != 0);
}
bool isValidIPv6(const QString &ip)
{
static unsigned char in6_any[16] = {};
in6_addr addr;
return (inet_pton(AF_INET6,&addr) == 1)
&& (memcmp(addr.s6_addr,in6_any,sizeof(in6_any)) != 0);
}
void FormSerial::PopCB(const QStringList &CB){
for (int i = 0; i < CB.size(); i += 2){
const QString &ip = CB.at(i);
if (IsValidIPv4(ip) || IsValidIPv6(ip)){
const QString &mac = CB.at(i+1);
Log("verdadero " + mac);
widget.Mac_ComboBox->addItem(mac);
}
}
}
bool IsValidIPv4(const sockaddr *addr)
{
return (addr->sa_family == AF_INET)
&& (reinterpret_cast<sockaddr_in*>(addr)->sin_addr.s_addr != 0);
}
bool IsValidIPv6(const sockaddr *addr)
{
static unsigned char in6_any[16] = {};
return (addr->sa_family == AF_INET6)
&& (memcmp(reinterpret_cast<sockaddr_in6*>(addr)->sin6_addr.s6_addr,sizeof(in6_any)) != 0);
}
void FormSerial::PopCB(const QStringList &CB){
addrinfo hints = {},*res;
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
for (int i = 0; i < CB.size(); i += 2){
if (getaddrinfo(CB.at(i).c_str(),NULL,&hints,&res) == 0){
if (IsValidIPv4(res->ai_addr) || IsValidIPv6(res->ai_addr)){
const QString &mac = CB.at(i+1);
Log("verdadero " + mac);
widget.Mac_ComboBox->addItem(mac);
}
freeaddrinfo(res);
}
}
}