6

我正在尝试在 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();
}

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

我的问题是如何区分 IP 地址和所有 IP 地址list

4

2 回答 2

11

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,你可能想重写它以使用信号和槽。

于 2012-10-17T05:53:19.030 回答
2

我认为,应该尝试几次尝试来增加 GUESS 的机会(无论软件多么聪明,它仍然是一个猜测,它不会涵盖 1% 的配置,这可能是你的情况:-)

我已经结合并扩展了这两种解决方案。首先,我会检查谷歌 DNS,然后检查具有标准网关的本地 IP。假设是:Getaway 具有与以“.1”结尾的地址相同的掩码。我不知道如何获得标准。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;
                }
            }   
        }
    }
于 2013-06-25T10:14:43.387 回答