超级好用的C++实用库之DNS解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
.cn 域名,1个 12个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 超级好用的C++实用库之DNS解析

概述

DNS(Domain Name System,域名系统)是一种分布式数据库服务,用于将人们容易记忆的域名与计算机网络中用于寻址和定位的IP地址进行映射。在互联网上,每一台设备都有一个唯一的IP地址。但由于IP地址通常是一串难以记忆的数字,因此DNS系统应运而生,它提供了一种将人类可读的、具有一定逻辑结构的域名转换为IP地址的服务。

当用户在浏览器中输入一个网址时,实际上是触发了一个DNS解析过程,这个过程包括如下步骤。

查询本地DNS缓存:首先检查本机是否有该域名对应的IP地址记录。

递归查询:如果没有命中缓存,则请求发送到用户的ISP提供的本地DNS服务器,由本地DNS服务器负责发起递归查询流程,逐级向上询问根域名服务器、顶级域名服务器以及权威域名服务器,直到找到目标域名的IP地址。

响应并缓存:一旦权威域名服务器返回了域名对应的IP地址,这个信息会沿着查询路径返回给用户,并被沿途的DNS服务器缓存起来,以加快后续相同域名的查询速度。

CHP_DNS类

在C++中,获取DNS域名对应的IP地址通常不直接通过编写原始的DNS查询协议来实现(虽然理论上可以这样做),而是调用操作系统提供的网络库或API来进行解析。这是因为直接处理DNS协议细节相当复杂且容易出错,而操作系统和标准库已经封装好了这些功能。

gethostbyname函数和getaddrinfo函数用于获取域名对应的IP地址,但这两个函数都是阻塞的。在非阻塞的使用场景下,直接使用这两个函数不太合适。为了方便应用层使用,我们封装了异步DNS解析类CHP_DNS。CHP_DNS类是一个单实例类,从CHP_BaseThread类派生。CHP_DNS类的头文件,可参考下面的示例代码。

#pragma once

#include <string>
#include <map>

#include "HP_BaseThread.h"
#include "HP_Mutex.h"

class CHP_DNS : public CHP_BaseThread
{
public:
    static void Open();
    static CHP_DNS *&Singleton();
    static void Close();
    
    unsigned int FetchIP(const char *pszIP);
    
    void DefetchIP(const char *pszIP);

    static int GetIP(const char *pszIP, unsigned int &uiIP);

protected:
    CHP_DNS();
    virtual ~CHP_DNS();

    virtual unsigned int Run();

private:
    typedef struct _TDNSInfo
    {
        _TDNSInfo()
        {
            uiIP = 0;
            uiLastGotTick = 0;
            uiLastActiveTick = 0;
        }

        unsigned int uiIP;
        unsigned int uiLastGotTick;
        unsigned int uiLastActiveTick;
    }TDNSInfo;

    typedef std::map<std::string, TDNSInfo> IPToDNSInfoMap;

    static CHP_DNS *m_pThis;
    IPToDNSInfoMap m_mapIPToDNSInfo;
    bool m_bMapChanged;
    CHP_Mutex m_mutexMap;
};

CHP_DNS类导出了两个实例成员函数和一个静态成员函数,下面分别进行介绍。

FetchIP:非阻塞获取DNS。参数pszIP为IP地址或域名;返回值为0时,表示没有解析成功,需要继续调用本函数,其他表示解析成功的IP地址。

DefetchIP:取消非阻塞获取DNS。当FetchIP一直返回0,上层判断超时后,最好调用本接口进行释放。否则,底层会一直尝试去解析,进而影响其他地址的解析过程。参数pszIP为IP地址或域名。

GetIP:阻塞获取DNS,静态函数。参数pszIP为IP地址或域名,参数uiIP为解析成功的IP地址,返回值为0表示成功,其他表示错误码。



相关文章
|
3月前
|
算法 C++ 容器
C++标准库(速查)总结
C++标准库(速查)总结
91 6
|
6天前
|
XML 网络协议 API
超级好用的C++实用库之服务包装类
通过本文对Boost.Asio、gRPC和Poco三个超级好用的C++服务包装类库的详细介绍,开发者可以根据自己的需求选择合适的库来简化开发工作,提高代码的效率和可维护性。每个库都有其独特的优势和适用场景,合理使用这些库可以极大地提升C++开发的生产力。
28 11
|
10天前
|
存储 算法 安全
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
|
2月前
|
自然语言处理 编译器 Linux
|
2月前
|
数据采集 JavaScript API
网页解析库:BeautifulSoup与Cheerio的选择
网页解析库:BeautifulSoup与Cheerio的选择
|
2月前
|
设计模式 安全 数据库连接
【C++11】包装器:深入解析与实现技巧
本文深入探讨了C++中包装器的定义、实现方式及其应用。包装器通过封装底层细节,提供更简洁、易用的接口,常用于资源管理、接口封装和类型安全。文章详细介绍了使用RAII、智能指针、模板等技术实现包装器的方法,并通过多个案例分析展示了其在实际开发中的应用。最后,讨论了性能优化策略,帮助开发者编写高效、可靠的C++代码。
43 2
|
23天前
|
安全 编译器 C++
C++ `noexcept` 关键字的深入解析
`noexcept` 关键字在 C++ 中用于指示函数不会抛出异常,有助于编译器优化和提高程序的可靠性。它可以减少代码大小、提高执行效率,并增强程序的稳定性和可预测性。`noexcept` 还可以影响函数重载和模板特化的决策。使用时需谨慎,确保函数确实不会抛出异常,否则可能导致程序崩溃。通过合理使用 `noexcept`,开发者可以编写出更高效、更可靠的 C++ 代码。
28 0
|
23天前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
61 0
|
2月前
|
自然语言处理 编译器 Linux
告别头文件,编译效率提升 42%!C++ Modules 实战解析 | 干货推荐
本文中,阿里云智能集团开发工程师李泽政以 Alinux 为操作环境,讲解模块相比传统头文件有哪些优势,并通过若干个例子,学习如何组织一个 C++ 模块工程并使用模块封装第三方库或是改造现有的项目。
|
2月前
|
存储 Go PHP
Go语言中的加解密利器:go-crypto库全解析
在软件开发中,数据安全和隐私保护至关重要。`go-crypto` 是一个专为 Golang 设计的加密解密工具库,支持 AES 和 RSA 等加密算法,帮助开发者轻松实现数据的加密和解密,保障数据传输和存储的安全性。本文将详细介绍 `go-crypto` 的安装、特性及应用实例。
112 0

推荐镜像

更多