如何检查网络地址是否在Qt本地 [英] How to check if network address is local in Qt

查看:213
本文介绍了如何检查网络地址是否在Qt本地的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道网络地址(名称或IP)是否指向远程服务器或本地计算机。我可以使用 QHostInfo 来查找IP地址,但在这种情况下,我必须等待DNS服务器的响应。我不想知道服务器的IP地址,我只需要检查它是否是本地的。

I want to know if network address (name or IP) points to remote server or local machine. I can use QHostInfo to lookup IP address, but in this case I would have to wait for DNS server's response. I don't want to know server's IP address, I only need to check if it is local or not. Is there any faster way to check this?

推荐答案


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

I can use QHostInfo to lookup IP address, but in this case I would have to wait for DNS server's response.

QHostInfo 使用特定于平台的名称解析机制。它可能不使用DNS。如果本地接口的主机名在hosts文件中,并且名称解析被配置为使用它,则 QHostInfo 将以这种方式解析本地接口的地址。

QHostInfo uses the platform-specific name resolution mechanism. It might not use DNS at all. If the hostname of a local interface is in the hosts file, and the name resolution is configured to use it, then QHostInfo will resolve the local interface's address that way. Otherwise, it'll do a name server query, iff the platform is configured to resolve names that way.

你可以做的最多的是检查 QHostAddress :: isLoopback(),然后检查它是否为 QNetworkInterface :: allAddresses()

The most you can do is to check QHostAddress::isLoopback(), then check if it's one of QNetworkInterface::allAddresses().

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

If your address is not an IP address, and it's not equal to QHostInfo::localHostName(), then you have to obtain one first using QHostInfo::lookupHost. If it's a local interface's name, listed in the hosts file or a similar local resolution mechanism, it will be returned quickly. You can set a short timeout (say 100ms), and if there's no lookup result available by then, you can assume that it's not a local interface.

// 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"

这篇关于如何检查网络地址是否在Qt本地的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆