当前位置:网站首页>QT5知识:DNS查询
QT5知识:DNS查询
2022-06-23 11:53:00 【无水先生】
一、说明
DNS查询,DNS通过层次结构的分布式数据库建立一致性的名字空间,用来定位网络资源。DNS查询过程可以分为本地查询、直接查询、递归查询和迭代查询。
二、常规查询方法
2.1、本地查询
主机保存有近期的DNS查询记录,这里面主要包含两块内容。一是hosts文件,文件保存在客户机系统盘中,文件路径是Windows/system32/drivers/etc/。另外一个是客户机的高速缓存,可以用ipconfig/displaydns查看。
如果主机发起DNS查询,首先查询hosts文件,然后在查询DNS缓存。如果hosts文件被恶意程序篡改,那么上网将异常,甚至还会打开不良网页。
很明显,本地缓存不会有http://qq.com的DNS记录。因此,主机向本地DNS服务器发起查询。
2.2、直接查询
本地DNS服务器是192.168.16.1,这是一个家庭路由器,本地DNS缓存里也不会有相应的DNS记录,因为它并不负责解析http://qq.com。因此,本地DNS服务器必须将查询请求转发至转发器。这个转发器即家庭路由器WAN口内设置的DNS地址,一般会有主备两个。
2.3、迭代查询
转发器按照域名级别高低,先后查询根服务器、.com域服务器、http://qq.com域服务器,最终得到授权应答。这个查询过程即迭代查询。
2.4、递归查询
转发器将相应的查询结果返回至本地DNS服务器192.168.16.1,本地DNS服务器将查询结果返回至主机,最终得出http://qq.com的ns记录。
三、参考代码
| dnslookup.h |
#include <QDnsLookup>
#include <QHostAddress>
//! [0]
struct DnsQuery
{
DnsQuery() : type(QDnsLookup::A) {}
QDnsLookup::Type type;
QHostAddress nameServer;
QString name;
};
//! [0]
class DnsManager : public QObject
{
Q_OBJECT
public:
DnsManager();
void setQuery(const DnsQuery &q) { query = q; }
public slots:
void execute();
void showResults();
private:
QDnsLookup *dns;
DnsQuery query;
};
| dnslookup.cpp |
#include "dnslookup.h"
#include <QCoreApplication>
#include <QDnsLookup>
#include <QHostAddress>
#include <QStringList>
#include <QTimer>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <stdio.h>
static int typeFromParameter(const QString &type)
{
if (type == "a")
return QDnsLookup::A;
if (type == "aaaa")
return QDnsLookup::AAAA;
if (type == "any")
return QDnsLookup::ANY;
if (type == "cname")
return QDnsLookup::CNAME;
if (type == "mx")
return QDnsLookup::MX;
if (type == "ns")
return QDnsLookup::NS;
if (type == "ptr")
return QDnsLookup::PTR;
if (type == "srv")
return QDnsLookup::SRV;
if (type == "txt")
return QDnsLookup::TXT;
return -1;
}
//! [0]
enum CommandLineParseResult
{
CommandLineOk,
CommandLineError,
CommandLineVersionRequested,
CommandLineHelpRequested
};
CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *query, QString *errorMessage)
{
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
const QCommandLineOption nameServerOption("n", "The name server to use.", "nameserver");
parser.addOption(nameServerOption);
const QCommandLineOption typeOption("t", "The lookup type.", "type");
parser.addOption(typeOption);
parser.addPositionalArgument("name", "The name to look up.");
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
if (!parser.parse(QCoreApplication::arguments())) {
*errorMessage = parser.errorText();
return CommandLineError;
}
if (parser.isSet(versionOption))
return CommandLineVersionRequested;
if (parser.isSet(helpOption))
return CommandLineHelpRequested;
if (parser.isSet(nameServerOption)) {
const QString nameserver = parser.value(nameServerOption);
query->nameServer = QHostAddress(nameserver);
if (query->nameServer.isNull() || query->nameServer.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
*errorMessage = "Bad nameserver address: " + nameserver;
return CommandLineError;
}
}
if (parser.isSet(typeOption)) {
const QString typeParameter = parser.value(typeOption);
const int type = typeFromParameter(typeParameter.toLower());
if (type < 0) {
*errorMessage = "Bad record type: " + typeParameter;
return CommandLineError;
}
query->type = static_cast<QDnsLookup::Type>(type);
}
const QStringList positionalArguments = parser.positionalArguments();
if (positionalArguments.isEmpty()) {
*errorMessage = "Argument 'name' missing.";
return CommandLineError;
}
if (positionalArguments.size() > 1) {
*errorMessage = "Several 'name' arguments specified.";
return CommandLineError;
}
query->name = positionalArguments.first();
return CommandLineOk;
}
//! [0]
DnsManager::DnsManager()
: dns(new QDnsLookup(this))
{
connect(dns, &QDnsLookup::finished, this, &DnsManager::showResults);
}
void DnsManager::execute()
{
// lookup type
dns->setType(query.type);
if (!query.nameServer.isNull())
dns->setNameserver(query.nameServer);
dns->setName(query.name);
dns->lookup();
}
void DnsManager::showResults()
{
if (dns->error() != QDnsLookup::NoError)
printf("Error: %i (%s)\n", dns->error(), qPrintable(dns->errorString()));
// CNAME records
const QList<QDnsDomainNameRecord> cnameRecords = dns->canonicalNameRecords();
for (const QDnsDomainNameRecord &record : cnameRecords)
printf("%s\t%i\tIN\tCNAME\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
// A and AAAA records
const QList<QDnsHostAddressRecord> aRecords = dns->hostAddressRecords();
for (const QDnsHostAddressRecord &record : aRecords) {
const char *type = (record.value().protocol() == QAbstractSocket::IPv6Protocol) ? "AAAA" : "A";
printf("%s\t%i\tIN\t%s\t%s\n", qPrintable(record.name()), record.timeToLive(), type, qPrintable(record.value().toString()));
}
// MX records
const QList<QDnsMailExchangeRecord> mxRecords = dns->mailExchangeRecords();
for (const QDnsMailExchangeRecord &record : mxRecords)
printf("%s\t%i\tIN\tMX\t%u %s\n", qPrintable(record.name()), record.timeToLive(), record.preference(), qPrintable(record.exchange()));
// NS records
const QList<QDnsDomainNameRecord> nsRecords = dns->nameServerRecords();
for (const QDnsDomainNameRecord &record : nsRecords)
printf("%s\t%i\tIN\tNS\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
// PTR records
const QList<QDnsDomainNameRecord> ptrRecords = dns->pointerRecords();
for (const QDnsDomainNameRecord &record : ptrRecords)
printf("%s\t%i\tIN\tPTR\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
// SRV records
const QList<QDnsServiceRecord> srvRecords = dns->serviceRecords();
for (const QDnsServiceRecord &record : srvRecords)
printf("%s\t%i\tIN\tSRV\t%u %u %u %s\n", qPrintable(record.name()), record.timeToLive(), record.priority(), record.weight(), record.port(), qPrintable(record.target()));
// TXT records
const QList<QDnsTextRecord> txtRecords = dns->textRecords();
for (const QDnsTextRecord &record : txtRecords) {
QStringList values;
const QList<QByteArray> dnsRecords = record.values();
for (const QByteArray &ba : dnsRecords)
values << "\"" + QString::fromLatin1(ba) + "\"";
printf("%s\t%i\tIN\tTXT\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(values.join(' ')));
}
QCoreApplication::instance()->quit();
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
//! [1]
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
QCoreApplication::setApplicationName(QCoreApplication::translate("QDnsLookupExample", "DNS Lookup Example"));
QCommandLineParser parser;
parser.setApplicationDescription(QCoreApplication::translate("QDnsLookupExample", "An example demonstrating the class QDnsLookup."));
DnsQuery query;
QString errorMessage;
switch (parseCommandLine(parser, &query, &errorMessage)) {
case CommandLineOk:
break;
case CommandLineError:
fputs(qPrintable(errorMessage), stderr);
fputs("\n\n", stderr);
fputs(qPrintable(parser.helpText()), stderr);
return 1;
case CommandLineVersionRequested:
printf("%s %s\n", qPrintable(QCoreApplication::applicationName()),
qPrintable(QCoreApplication::applicationVersion()));
return 0;
case CommandLineHelpRequested:
parser.showHelp();
Q_UNREACHABLE();
}
//! [1]
DnsManager manager;
manager.setQuery(query);
QTimer::singleShot(0, &manager, SLOT(execute()));
return app.exec();
}
边栏推荐
- Video data annotation tools and platforms (data annotation company)
- CIFAR公开第二阶段泛加拿大AI战略
- Getting started with redis - Chapter 4 - data structures and objects - jump table
- 我在佛山,到哪里开户比较好?手机开户安全么?
- 09 -- 回文对
- [processes and threads]
- KDD 2022 | 基于分层图扩散学习的癫痫波预测
- 电感有极性吗?
- 过采样系列二:傅里叶变换与信噪比
- Daily question 7-1652 Defuse the bomb
猜你喜欢

Analysis of six dimensional chart: analysis of enterprise growth of CSCEC

切比雪夫不等式证明及应用

Easy to understand soft route brushing tutorial

华为云如何实现实时音视频全球低时延网络架构

"Dream of children's travel" in 2022, GAC Honda children's road safety charity travel entered the Northeast

蓝桥杯单片机(一)——关闭外设及熄灭LED

Proof and application of Chebyshev inequality

Comment Huawei Cloud réalise l'architecture mondiale de réseau audio - vidéo en temps réel à faible latence

Leetcode 1209. Delete all adjacent duplicates II in the string

php 手写一个完美的守护进程
随机推荐
[zero foundation wechat applet] actual development of ID photo changing background color applet based on Baidu brain portrait segmentation
@黑马粉丝,这份「高温补贴」你还没领?
Which securities company is the most reliable and safe to open an account
1路百兆光纤收发器1百兆光1百兆电桌面式以太网光纤收发器内置电源
Face the future calmly and strive to improve yourself
股权转让热点:重庆建科建设工程质量检测有限公司93.75%股权转让
2022年全国最新消防设施操作员(初级消防设施操作员)模拟题及答案
tensorflow2的GradientTape求梯度
Redis 入门-第三篇-数据结构与对象-字典
全国进入主汛期,交通运输部:不具备安全运行条件的线路坚决停运!
OpenHarmony应用开发【01】
Introduction to redis - Chapter 1 - data structures and objects - simple dynamic string (SDS)
From 0 to 1, how does the IDE improve the efficiency of end-to-end R & D| DX R & D mode
[comprehensive written test questions] 30 Concatenate substrings of all words
Gradienttape of tensorflow2
请问,maxcompute执行sql查询有时特别慢是什么原因
At 14:00 today, 12 Chinese scholars started ICLR 2022
[cloud resident co creation] in the code free era, how does software development go to everyone?
爱可可AI前沿推介(6.23)
4路电话+1路千兆以太网4路PCM电话光端机