从 QStringList 解析 ip/mac 广告

parsing the ip/mac adrs from a QStringList

我正在尝试为我正在制作的许可程序解析和显示我机器的 MAC 地址,但只显示具有有效 IP 地址的地址。我已经收到了 IPs/MACs,但我看不出哪个有效,哪个无效。

这是我的代码:

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, so you are better off using an API/library that knows how to parse IP address strings, such as inet_pton() or 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, ip.c_str(), &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, in6_any, 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);
        }
    }
}