如何使用QT获取计算机的本地IP地址

How to get local IP address of a computer using QT

本文关键字:IP 地址 计算机 何使用 QT 获取      更新时间:2023-10-16

我正在尝试获取QT中计算机的本地IP地址(IPv4)。我找到了以下代码:

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

通过循环我可以看到list中有许多值(IP),其中之一是我通过在命令窗口中键入ipconfig获得的实际本地IP地址。

我的问题是如何将IP地址与list中的所有IP区分开?

PC通常具有多个IP地址。实际上没有"本地IP地址"这样的事情;连接到某些远程主机时将使用的IP地址至少取决于本地路由表(例如,在启动/停止VPN软件时可能会发生巨大变化)。

在我看来,只有在远程网络的上下文中,将IP视为有效,例如"如果我要在Internet上连接到此主机,这是我使用的本地IP地址;但这是我用来通过公司VPN连接到此主机的本地IP地址。

如果您想找出用于通用Internet连接性的本地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();
}

注意:上面的示例是阻塞,如果您的应用程序具有UI。

我认为,应该尝试多次尝试增加猜测的机会(无论软件有多聪明,这仍然是一个猜测,这将不涵盖1%的配置您可能会遇到什么: - )

我已经合并并扩展了这两个解决方案。首先,我会检查Google DNS,然后检查具有标准网关的本地IP。假设是:"逍遥游"具有与" .1"结尾的addreess相同的掩码。我找不到,如何获得性病。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;
                }
            }   
        }
    }