Как получить локальный IP-адрес компьютера с помощью QT

Я пытаюсь получить локальный IP-адрес (IPV4) компьютера в QT. Я нашел следующий код:

QNetworkInterface *inter = new QNetworkInterface();
QList<QHostAddress> list;
list=inter->allAddresses();
QString str;

for (int i = 0; i < list.size(); ++i) {
     str = list.at(i).toString();
}

Проходя цикл for, я вижу, что в list есть несколько значений (ip-адресов), одно из них — фактический локальный IP-адрес, который я получаю, набрав ipconfig в командном окне.

Мой вопрос: как отличить IP-адрес от всех IP-адресов, которые находятся в list?


person TJ1    schedule 17.10.2012    source источник
comment
Отфильтруйте интерфейсы, возвращенные allInterfaces(), используя пару эти флаги.   -  person Blender    schedule 17.10.2012
comment
Компьютеры могут иметь несколько интерфейсов Ethernet (и часто имеют, скажем, Wi-Fi и проводной), поэтому они могут иметь более одного IP-адреса. Вам нужно сузить то, что вы подразумеваете под локальным IP-адресом компьютера.   -  person PherricOxide    schedule 17.10.2012
comment
Допустим, мне нужен адрес IPV4 адаптера беспроводной локальной сети, а затем тот, который ipconfig в командной строке,   -  person TJ1    schedule 17.10.2012


Ответы (2)


ПК часто имеют более одного IP-адреса. На самом деле не существует такой вещи, как «локальный IP-адрес»; IP-адрес, который будет использоваться при подключении к какому-либо удаленному хосту, зависит как минимум от локальной таблицы маршрутизации (которая может резко измениться в любой момент, например, при запуске/остановке программного обеспечения VPN).

Мне кажется, что разумнее думать об IP-адресах как о действительных только в контексте удаленных сетей, например. «это локальный IP-адрес, который я бы использовал, если бы мне нужно было подключиться к этому хосту в Интернете; но это локальный IP-адрес, который я бы использовал для подключения к этому хосту через VPN моей компании».

Если вы хотите узнать локальный IP-адрес, который будет использоваться для общего подключения к Интернету, самый точный способ, который я знаю, — это просто выполнить тест подключения к репрезентативному хосту (и хосту с высокой надежностью!)

QTcpSocket socket;
socket.connectToHost("8.8.8.8", 53); // google DNS, or something else reliable
if (socket.waitForConnected()) {
    qDebug()
        << "local IPv4 address for Internet connectivity is"
        << socket.localAddress();
} else {
    qWarning()
        << "could not determine local IPv4 address:"
        << socket.errorString();
}

Примечание: приведенный выше пример является блокирующим, вы, вероятно, захотите переписать его, чтобы использовать сигналы и слоты, если ваше приложение имеет пользовательский интерфейс.

person rohanpm    schedule 17.10.2012
comment
Это хороший способ сделать это, однако, что произойдет, если ПК подключен к маршрутизатору (IP-адрес назначается ПК маршрутизатором), но маршрутизатор не подключен к Интернету? Например, если у вас есть только локальная сеть? - person TJ1; 17.10.2012
comment
Тогда этот метод правильно определит, что нет локального IP-адреса, пригодного для подключения к Интернету; в этом случае вы можете заменить (8.8.8.8, 53) каким-либо хостом, к которому вы можете подключиться. Если вы не знаете о таком хосте, я бы сказал, что разумным значением по умолчанию будет любой настроенный первичный DNS-сервер (обычно отправляемый маршрутизатором в ответе DHCP). Но я не знаю, как получить эту информацию с помощью Qt :( - person rohanpm; 17.10.2012
comment
Спасибо, я подожду, если не будет полного ответа, я приму ваш ;-) - person TJ1; 17.10.2012
comment
DNS работает по UDP, а не по TCP - person frogatto; 09.06.2015

Я думаю, что следует попробовать несколько попыток, чтобы увеличить вероятность УГАДКИ (независимо от того, насколько умна программа, это все равно будет догадкой, которая не покроет 1% конфигураций, которые, возможно, будут в вашем случае :-)

Я объединил и расширил оба решения. Сначала я бы проверил DNS Google, а затем локальные IP-адреса со стандартным шлюзом. Предположение: Getaway имеет ту же маску с адресом, заканчивающимся на «.1». Я не мог узнать, как получить std. шлюз в Qt (что было бы надежнее).

Вот код, который работает НА МОИХ КОМПЬЮТЕРАХ:

    QTcpSocket dnsTestSocket;   
    QString localIP="127.0.0.1";    //fall back
    QString googleDns = "8.8.8.83";  //try google DNS or sth. else reliable first
    dnsTestSocket.connectToHost(googleDns, 53);
    if (dnsTestSocket.waitForConnected(3000)) 
    {
        localIP = dnsTestSocket.localAddress().toString();
    } 
    else 
    {
        foreach (const QHostAddress &address, QNetworkInterface::allAddresses())
        {
            QString guessedGatewayAddress = address.toString().section( ".",0,2 ) + ".1";

            if (address.protocol() == QAbstractSocket::IPv4Protocol 
                && address != QHostAddress(QHostAddress::LocalHost)
                )
            {
                dnsTestSocket.connectToHost(guessedGatewayAddress, 53);
                if (dnsTestSocket.waitForConnected(3000))
                {
                    localIP = dnsTestSocket.localAddress().toString();
                    break;
                }
            }   
        }
    }
person Community    schedule 25.06.2013