2016-03-30 68 views
1

我想知道网络地址(名称或IP)是否指向远程服务器或本地计算机。我可以使用QHostInfo查找IP地址,但在这种情况下,我将不得不等待DNS服务器的响应。我不想知道服务器的IP地址,我只需要检查它是否是本地的。有没有更快的方法来检查这个?如何检查网络地址是否在本地Qt

+1

什么是本地地址吗? – gomons

+0

我想知道地址是否是回送地址,别名(如本地主机)或全局IP地址指向本地机器。 –

回答

0

我可以使用QHostInfo来查找IP地址,但在这种情况下,我将不得不等待DNS服务器的响应。

QHostInfo使用平台特定的名称解析机制。它可能根本不使用DNS。如果本地接口的主机名在主机文件中,并且名称解析配置为使用它,则QHostInfo将以这种方式解析本地接口的地址。否则,它将执行名称服务器查询,如果平台配置为通过这种方式解析名称。

您可以做的最多的是检查QHostAddress::isLoopback(),然后检查它是否是QNetworkInterface::allAddresses()之一。

如果您的地址不是IP地址,并且不等于QHostInfo::localHostName(),那么您必须先使用QHostInfo::lookupHost获取一个。如果是主机文件或类似的本地解析机制中列出的本地接口名称,它将很快返回。你可以设置一个短暂的超时(比如说100ms),如果到那时还没有可用的查找结果,你可以假设它不是本地接口。

下面是一个例子:

// https://github.com/KubaO/stackoverflown/tree/master/questions/host-lookup-36319049 
#include <QtWidgets> 
#include <QtNetwork> 

class IfLookup : public QObject { 
    Q_OBJECT 
    int m_id; 
    QTimer m_timer; 
    void abort() { 
     if (m_timer.isActive()) 
     QHostInfo::abortHostLookup(m_id); 
     m_timer.stop(); 
    } 
    Q_SLOT void lookupResult(const QHostInfo & host) { 
     m_timer.stop(); 
     if (host.error() != QHostInfo::NoError) 
     return hasResult(Error); 
     for (auto ifAddr : QNetworkInterface::allAddresses()) 
     if (host.addresses().contains(ifAddr)) 
      return hasResult(Local); 
     return hasResult(NonLocal); 
    } 
public: 
    enum Result { Local, NonLocal, TimedOut, Error }; 
    IfLookup(QObject * parent = 0) : QObject(parent) { 
     connect(&m_timer, &QTimer::timeout, this, [this]{ 
     abort(); 
     emit hasResult(TimedOut); 
     }); 
    } 
    Q_SIGNAL void hasResult(Result); 
    Q_SLOT void lookup(QString name) { 
     abort(); 
     name = name.trimmed().toUpper(); 
     QHostAddress addr(name); 
     if (!addr.isNull()) { 
     if (addr.isLoopback() || QNetworkInterface::allAddresses().contains(addr)) 
      return hasResult(Local); 
     return hasResult(NonLocal); 
     } 
     if (QHostInfo::localHostName() == name) 
     return hasResult(Local); 
     m_id = QHostInfo::lookupHost(name, this, SLOT(lookupResult(QHostInfo))); 
     m_timer.start(500); 
    } 
}; 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    QWidget w; 
    QFormLayout layout{&w}; 
    QLineEdit address; 
    layout.addRow("Address to look up", &address); 
    QLabel result; 
    layout.addRow("Result", &result); 
    QPushButton lookup{"Lookup"}; 
    layout.addRow(&lookup); 
    lookup.setDefault(true); 
    w.show(); 

    IfLookup ifLookup; 
    QObject::connect(&lookup, &QPushButton::clicked, [&]{ 
     result.clear(); 
     ifLookup.lookup(address.text()); 
    }); 
    QObject::connect(&ifLookup, &IfLookup::hasResult, [&](IfLookup::Result r){ 
     static const QMap<IfLookup::Result, QString> msgs = { 
     { IfLookup::Local, "Local" }, { IfLookup::NonLocal, "Non-Local" }, 
     { IfLookup::TimedOut, "Timed Out" }, { IfLookup::Error, "Lookup Error" } 
     }; 
     result.setText(msgs.value(r)); 
    }); 

    return app.exec(); 
} 

#include "main.moc" 
相关问题