【问题标题】:Get current QNetworkInterface active and connected to the internet激活当前的 QNetworkInterface 并连接到互联网
【发布时间】:2011-04-06 20:00:40
【问题描述】:

我想激活当前的网络接口并连接到互联网。

实际上,我可以检查网络是否已启动,以及是否不是环回网络。

  foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())
    {
        if (interface.flags().testFlag(QNetworkInterface::IsUp) && !interface.flags().testFlag(QNetworkInterface::IsLoopBack))
            foreach (QNetworkAddressEntry entry, interface.addressEntries())
            {
            if ( interface.hardwareAddress() != "00:00:00:00:00:00" && entry.ip().toString().contains("."))
                items << interface.name() + " "+ entry.ip().toString() +" " + interface.hardwareAddress();
        }

结果:

"en1 3.3.3.52 D4:9A:20:61:1F:72" 
"vmnet1 192.168.169.1 00:50:56:C0:00:01" 
"vmnet8 192.168.210.1 00:50:56:C0:00:08"

事实上它可以工作,但我也发现了 VM 接口。 而且我只想选择WLAN接口和以太网接口。

【问题讨论】:

  • 您发布的代码块有什么问题?
  • @Adam:我猜他不知道接口是否处于活动状态。
  • 如果您只需要 WLAN 和以太网接口,使用 VPN 的人会感到失望。通常这是他们与互联网的唯一连接。
  • 我想我的问题是:定义“连接到互联网”(比你想象的更难回答)

标签: c++ qt network-interface


【解决方案1】:

我知道这个问题很老,但我正在研究类似的问题。

这是我的解决方案:

  foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())
    {
        if (interface.flags().testFlag(QNetworkInterface::IsUp) && !interface.flags().testFlag(QNetworkInterface::IsLoopBack))
            foreach (QNetworkAddressEntry entry, interface.addressEntries())
            {
            if ( interface.hardwareAddress() != "00:00:00:00:00:00" && entry.ip().toString().contains(".") && !interface.humanReadableName().contains("VM"))
                items << interface.name() + " "+ entry.ip().toString() +" " + interface.hardwareAddress();
        }

我刚刚添加了

&amp;&amp; !interface.humanReadableName().contains("VM")

到你的第二个 if 语句。现在它不会列出包含字符串“vm”的适配器。

希望这对其他人也有帮助。

【讨论】:

    【解决方案2】:

    很抱歉再次提出一个老问题,但我自己只是在思考这个问题并想出了一个解决方案:

    QList<QString> possibleMatches;
    QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
    if ( !ifaces.isEmpty() )
    {
      for(int i=0; i < ifaces.size(); i++)
      {
        unsigned int flags = ifaces[i].flags();
        bool isLoopback = (bool)(flags & QNetworkInterface::IsLoopBack);
        bool isP2P = (bool)(flags & QNetworkInterface::IsPointToPoint);
        bool isRunning = (bool)(flags & QNetworkInterface::IsRunning);
    
        // If this interface isn't running, we don't care about it
        if ( !isRunning ) continue;
        // We only want valid interfaces that aren't loopback/virtual and not point to point
        if ( !ifaces[i].isValid() || isLoopback || isP2P ) continue;
        QList<QHostAddress> addresses = ifaces[i].allAddresses();
        for(int a=0; a < addresses.size(); a++)
        {
          // Ignore local host
          if ( addresses[a] == QHostAddress::LocalHost ) continue;
    
          // Ignore non-ipv4 addresses
          if ( !addresses[a].toIPv4Address() ) continue;
    
          QString ip = addresses[a].toString();
          if ( ip.isEmpty() ) continue;
          bool foundMatch = false;
          for (int j=0; j < possibleMatches.size(); j++) if ( ip == possibleMatches[j] ) { foundMatch = true; break; }
          if ( !foundMatch ) { possibleMatches.push_back( ip ); qDebug() << "possible address: " << ifaces[i].humanReadableName() << "->" << ip; }
        }
      }
    }
    // Now you can peek through the entries in possibleMatches
    // With VMWare installed, I get two entries, and the first one is the correct one.
    // If you wanted to test which one has internet connectivity, try creating a tcp
    // connection to a known internet service (e.g. google.com) and if the connection
    // is successful, check the following on the tcp connection
    /*
    if ( socket->localAddress().toIPv4Address() )
    {
      for(int c=0; c < possibleMatches.size(); c++) if ( socket->localAddress().toString() == possibleMatches[c] ) { qDebug() << "Your LAN IP:" << possibleMatches[c]; }
    }
    */
    

    你可能想让它更健壮一点,这样代码就可以同时跟踪接口和 IP 地址,但这可能是不必要的,因为我很确定一个接口不能容纳多个ip 地址,并且没有两个接口可以具有相同的 IP 地址(如果我在这个假设上错了,请纠正我)。

    【讨论】:

    • 你可能想使用 ifaces[i].addressEntries(),因为 .allAddresses() 是一个静态方法,它从所有网络接口返回 ips。
    【解决方案3】:

    使用enum QNetworkInterface::InterfaceFlag 获取此信息。

    QNetworkInterface::IsUp         0x1 the network interface is active
    QNetworkInterface::IsRunning    0x2 the network interface has resources allocated
    QNetworkInterface::CanBroadcast 0x4 the network interface works in broadcast mode
    QNetworkInterface::IsLoopBack   0x8 the network interface is a loopback interface: that is, it's a virtual interface whose destination is the host computer itself
    QNetworkInterface::IsPointToPoint   0x10    the network interface is a point-to-point interface: that is, there is one, single other address that can be directly reached by it.
    QNetworkInterface::CanMulticast 0x20    the network interface supports multicasting
    

    来自Qt 4.7 documentation

    【讨论】:

    • 实际上这段代码显示所有接口处于活动状态,但我不想选择 physiq 接口而不是 vm 接口你有什么想法吗?
    【解决方案4】:
    for windows
    // return -- interface ipv4 entry, interface type
    QList<QPair<QHostAddress,QNetworkInterface::InterfaceType>> getActiveNetworks()
    {
        QProcess m_process;
        QStringList param;param<<"Get-NetAdapter -physical | where status -eq 'up' |Format-List -Property \"MacAddress\"";
        m_process.start("powershell",param);
        m_process.waitForFinished();
        QString result =  m_process.readAllStandardOutput();
        QStringList resultList = result.split("\r\n\r\n");
        resultList.removeAll("");
        QStringList macAddressList;
        for(auto maclist :resultList)
        {
            QString temp = maclist.split(':').at(1);
            temp.remove(' ');
            temp.replace('-',':');
            macAddressList.append(temp);
        }
        QList<QPair<QHostAddress,QNetworkInterface::InterfaceType>> networks;
        for(auto interface:QNetworkInterface::allInterfaces())
        {
            if(macAddressList.contains(interface.hardwareAddress()))
                for(QNetworkAddressEntry address:interface.addressEntries())
                   if(address.ip().toIPv4Address())
                    networks.append(QPair<QHostAddress,QNetworkInterface::InterfaceType>
                                (address.ip(),interface.type()));
        }
        return networks;
    }
    

    【讨论】:

      【解决方案5】:

      使用QTcpSocket 建立 TCP 连接。接下来,获取它的.localAddress。您可能会发现互联网的不同部分对应不同的本地地址。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-17
        • 1970-01-01
        • 1970-01-01
        • 2015-01-02
        • 1970-01-01
        相关资源
        最近更新 更多