Получить текущий QNetworkInterface активным и подключенным к Интернету

Я хотел бы активировать текущий сетевой интерфейс и подключить его к Интернету.

На самом деле, я могу проверить, работает ли сеть и не является ли сеть обратной петлей.

  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 и интерфейсы Ethernet.


person menkel    schedule 06.04.2011    source источник
comment
Что не так с блоком кода, который вы разместили?   -  person Adam Batkin    schedule 07.04.2011
comment
@Adam: Я предполагаю, что он не знает, активен интерфейс или нет.   -  person    schedule 07.04.2011
comment
Если вам нужны только интерфейсы WLAN и Ethernet, люди с VPN будут разочарованы. Часто это их единственное подключение к Интернету.   -  person MSalters    schedule 07.04.2011
comment
Я предполагаю, что мой вопрос: Определите, подключен ли он к Интернету (на него сложнее ответить, чем вы думаете)   -  person Adam Batkin    schedule 08.04.2011


Ответы (4)


Извините, что возрождаю старый вопрос, но я просто обдумывал это сам и придумал решение:

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-адрес (поправьте меня, если я ошибаюсь в этом предположении).

person OzBarry    schedule 29.05.2013
comment
Вероятно, вы хотели использовать ifaces[i].addressEntries(), потому что .allAddresses() — это статический метод, который возвращает ips со всех сетевых интерфейсов. - person Zmey; 24.08.2018

Я знаю, что вопрос старый, но я работаю над чем-то подобным.

Вот мое решение:

  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();
        }

Я только что добавил

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

к вашему второму оператору if. Теперь он не отображает адаптеры, содержащие строку «vm».

Надеюсь, это поможет и другим людям.

person Aschi33    schedule 22.05.2015

Используйте 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.

person Community    schedule 06.04.2011
comment
на самом деле этот код показывает, что все интерфейсы активны, но я не хочу выбирать интерфейс physiq, а не интерфейс vm. У вас есть идеи? - person menkel; 07.04.2011

Настройте TCP-соединение с помощью QTcpSocket. Затем получите его .localAddress. Вы можете обнаружить, что разные части Интернета соответствуют разным локальным адресам.

person MSalters    schedule 07.04.2011