如何进行域名解析?如何清理DNS缓存?(附源码)

news2025/2/23 16:24:03

目录

1、什么是域名?

2、为什么使用域名?

3、域名解析的完整流程

4、调用gethostbyname系统接口将域名解析成IP地址

5、为什么需要清理系统DNS缓存?

6、使用cmd命令清理DNS缓存

7、通过代码去清除系统DNS缓存


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html       当我们使用域名访问远端的服务器时,需要先将域名转换成IP地址,然后通过IP地址去连接远端的服务器。这个将域名转换成IP地址的过程就叫做域名解析。操作系统中会将最近解析过的域名与IP地址缓存起来,称之为DNS缓存,有时可能需要清理DNS缓存,重新获取最新的IP地址。今天就给大家介绍一下如何进行域名解析及域名解析的完整流程,以及如何刷新DNS缓存,以供大家借鉴或参考。

1、什么是域名?

        域名是指互联网中的网站或者服务器的地址,这些名称由多个字符组成,通常是以“.com”、“.net”、“.cn”等结尾,比如大家常用的www.baidu.com(百度)、www.163.com(网易)等。一个好的域名,是连接客户和企业的桥梁,可以增加企业的知名度,使得客户更加容易地找到它们的网站,提高客户的转化率。

2、为什么使用域名?

       首先,域名便于记忆。由于IP地址不方便记忆且不能显示地址组织的名称和性质,人们设计出了域名,并通过域名系统(DNS,Domain Name System)来将域名和IP地址相互映射。域名好记忆很多,使人能更方便地访问互联网,而不用去记住能够被机器直接读取的IP地址数串。

       其次,远端服务器的IP可能会变动。域名一旦确定下来,一般就不会频繁地更改,特别是百度和网易这种门户网站,用户习惯使用固定的域名去访问指定的网站。但域名对应的IP地址可能会变更,在IP地址变更后,用户还能正常地通过域名去访问(对域名进行解析获取最新的IP地址)。

       此外,同一个域名可能会配置多个IP地址,不同的IP地址对应着不同的运营商线路,比如移动线路、电信线路和联通线路(不同的用户可能使用不同运营商的网络),从不同线路进来的,会解析出对应线路的IP地址,这样就避免了跨运营商网络访问,可以有效地提高访问的速度。

有的客户端软件支持用户去配置要访问的服务器地址,可以直接添加域名地址。有的软件则会内置要访问的服务器域名,不需要将服务器地址的配置暴露给用户(没有提供配置远端服务器地址的入口),软件在登录时直接使用内置的域名地址登录远端的服务器,比如QQ、微信及企业微信等。

3、域名解析的完整流程

       在进行域名解析时,底层会使用专用的DNS域名查询协议去查询域名对应IP地址。一般我们不需要关注DNS查询协议具体的格式和交互过程,我们只需要了解查询的大概流程即可。下面我们就来详细介绍一下域名解析的完整流程。

       DNS服务器大致分为三种类型:根DNS服务器、顶级域DNS服务器和权威DNS服务器,其中顶级域DNS服务器主要负责诸如com、org、net、edu、gov 等顶级域名,如下:

       根DNS服务器存储了所有顶级域DNS服务器的 IP 地址,可以通过根服务器找到顶级域服务器,比如百度的域名www.baidu.com,根服务器会返回所有维护 com 这个顶级域服务器的 IP 地址。然后你任选其中一个顶级域服务器发送请求,该顶级域服务器拿到域名后能够给出负责当前域的权威服务器地址。以百度的域名为例,顶级域服务器将返回所有负责百度这个域的权威服务器地址。接着任选其中一个权威服务器地址查询“www.baidu.com”的具体 IP 地址,最终权威服务器会返回给你具体的 IP 地址。此外,本地 DNS 服务器是具有缓存功能的,通常两天内的记录都会被缓存。

       所以,通过DNS系统查询域名对应的 IP 的具体步骤如下

  • ① 操作系统先查本地 hosts文件 中是否有记录,如果有,则直接返回相对应映射的IP地址。hosts文件位于C:\Windows\System32\drivers\etc路径中,内容如下:

  • ② 如果本地hosts文件中没有配置,则主机向自己的本地DNS服务器发送查询报文,如果本地DNS服务器缓存中有,将直接返回结果。
  • ③ 如果本地服务器缓存中没有(操作系统中会有DNS缓存),则从内置在内部的根DNS服务器列表(全球13台,固定的IP地址)中选一个发送查询报文。
  • ④ 根服务器解析域名中的后缀名,告诉本地服务器负责该后缀名的所有顶级服务器列表。
  • ⑤ 本地服务器选择其中一个顶级域服务器发送查询请求,顶级域服务器拿到域名后继续解析,返回对应域的所有权威服务器列表。
  • ⑥ 本地服务器再向返回的权威服务器发送查询报文,最终会从某一个权威服务器上得到具体的 IP 地址。
  • ⑦ 主机返回结果IP

        在这里,给大家重点推荐一下我的几个热门畅销专栏(博客主页还有其他专栏,可以去查看)

专栏1:(该精品技术专栏的订阅量已达到430多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!)

C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2: 

C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战经验为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对C++相关知识点进行详细地展开与剖析!专栏涉及了C/C++开发领域多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!

专栏3: 

VC++常用功能开发汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585

专栏将10多年C++开发实践中常用的功能,以高质量的代码展现出来,并对相关功能的实现细节进行了详细的说明。这些常用的代码,其质量与稳定性是有保证的,可以直接拿过去使用,可以有效地解决C++软件开发过程中遇到的问题。


4、调用gethostbyname系统接口将域名解析成IP地址

       当我们使用客户端软件或者浏览器通过域名访问远端的服务器时,作为用户是不感知域名解析的过程的,如果当前使用的是浏览器,则由浏览器去负责进行域名解析;如果当前使用的是客户端软件,则由客户端软件通过代码去完成域名解析。

       那如何通过代码将域名解析成IP地址呢?其实很简单,只要调用系统API函数gethostbyname即可实现。

注意,gethostbyname函数可能会产生短暂的堵塞,该函数内部会先到系统DNS缓存中去查找;如果没找到,则到网卡上配置的DNS服务器上去查询域名对应的IP地址;如果本地DNS查询不到,则会到远端的DNS服务器上去查询,所以这个域名解析的过程可能会比较耗时。至于DNS域名的详细查询过程,文章开始时已经详细讲述,此处就不再赘述了。

       所以,我们需要将对gethostbyname函数调用的代码,放置在一个新的线程中,等解析出来后再将IP信息投递出来给主线程。相关的代码如下所示:

// 域名解析线程函数
UINT __stdcall QueryDomainThread( LPVOID pParam )
{
	char* lpszDomainName = (char*)pParam; 
 
	struct hostent *pHost = gethostbyname( lpszDomainName ); 
	if( NULL == pHost )  
	{   
		// ::PostMessage // 通知主线程域名解析失败
		return 0;   
	}
 
	if ( pHost->h_addr_list[0] != NULL ) 
	{ 
		u32 dwIP = (*(in_addr*)pHost->h_addr_list[0]).S_un.S_addr; 
		// ::PostMessage // 通知主线程域名解析成功,将解析出来的IP投递过去
	}  
 
	return 0; 
}
 
// 发起域名解析,创建新的线程去解析
LRESULT StartQueryDomain( char* lpszDomainName )
{
	// 此处不能直接将局部变量lpszDomainName传到线程函数中,因为启动线程的_beginthreadex返回时,线程函数不一定跑起来了
	// 所以最好搞一个成员变量或者全局变量,将lpszDomainName中的字符串拷贝下来,然后给_beginthreadex传递这个声明周期
	// 更长的变量
	strcpy( g_szMDomainName, lpszDomainName );
 
    // 线程函数QueryDomainThread的实现,上面已经给出
	HANDLE hThread= (HANDLE)_beginthreadex( NULL, 0, QueryDomainThread, (void*)g_szMDomainName, 0, NULL );
	if( hThread != NULL )
	{
		CloseHandle( hThread );
		return S_OK;
	}
 
	return S_FALSE;
}

5、为什么需要清理系统DNS缓存?

       假设服务器的IP地址变更,但我们PC端的系统DNS缓存中没有更新(我们在实际项目中遇到过),根据上面讲到的域名解析的流程,我们PC客户端软件使用域名访问远端的服务器时,发现本端系统DNS缓存中存放有域名对应的IP地址,就会直接从缓存中取出IP地址,就不会再向DNS服务器请求IP地址了。

系统之所以要建立系统DNS缓存,目的是为了提高应用访问服务器的效率,进行域名解析时如果系统缓存中目标域名对应的IP记录,直接取出来使用即可,就不用每次都向域名服务器发起域名查询请求,有效地减少了域名解析的时间。但DNS缓存也有不好的影响,比如此处的问题。

但从系统DNS缓存中取出的是老的IP地址,服务器IP地址已经变更,所以也就无法访问到服务器了。

       当遇到这类可以连外网但服务器无法访问时,可能是系统DNS缓存引起的,可以尝试清理一下系统DNS缓存,这样在解析域名时就会向DNS服务器发起域名查询请求,就能查询到最新的IP地址了,也就能正常地访问到服务器了。

6、使用cmd命令清理DNS缓存

       可以直接在cmd命令行窗口中使用ipconfig /flushdns命令即可清理系统的DNS缓存,如下所示:

这个命令其实是调用系统程序ipconfig.exe,在程序启动时给程序传递命令行参数/flushdns,程序启动起来后检测到命令行参数/flushdns,就会去执行清理DNS缓存的操作。

       我们还可以使用ipconfig /displaydns命令去查看系统DNS缓存中的信息,如下所示:

DNS缓存中存放着一条一条域名解析记录,每一条记录中的字段说明如下:

1)记录名称:是您查询 DNS 的名称,并且记录(地址或其他内容)属于该名称。
2)记录类型:是显示为数字的类型 - 尽管更常见的是通过名称来引用它们,但在内部(在 DNS 协议中)每个都有一个数字。类型 1 是“A”,表示“地址”,即 IPv4 地址。(IPv6 使用类型 28,“AAAA”,作为地址的四倍。)“PTR”,类型 12,是指向主机名的“指针”——最常用于将 IP 地址映射回其名称。“CNAME”是“规范名称”。
3)生存时间:是缓存条目必须到期的时间(以秒为单位)。
4)数据长度:似乎是以字节为单位的长度 - IPv4 地址为四个字节,IPv6 为十六个字节。对于 CNAME 或 PTR,Windows 显示一个静态数字(4 或 8,取决于您的系统)——这实际上是保存实际文本的内存地址的大小。
DNS 回复的“答案”部分是查询的实际答案,“附加”部分包含查找实际答案可能需要的信息。例如,粘合记录。
5)<type>记录:显示存储的实际值。

7、通过代码去清除系统DNS缓存

       上面我们说了,在cmd中执行系统DNS缓存清理的命令其实就是给系统程序ipconfig.exe传递了/flushdns参数,ipconfig.exe程序内部应该是调用系统库中的接口去实现清理的。于是在系统目录中找到ipconfig.exe文件,然后拖入到Dependency Walker工具中,看看ipconfig.exe有没有引用系统DNS相关的库以及调用了哪个具体的接口

       拖入后看到ipconfig.exe引用了系统库DNSAPI.dll,并看到调用了该库中的DnsFlushResolverCache接口:

于是到微软MSDN上搜索DnsFlushResolverCache函数,但并没有搜索到,那基本可以确定该接口是没有公开的。

       对于这类非公开的API函数,那可以使用LoadLibrary显示加载,并用GetProcess得到函数指针,直接调用之即可通过搜索,得到该函数的原型声明:

BOOL  WINAPI  DnsFlushResolverCache(VOID);

所以,从DNSAPI.DLL动态库中显式加载调用DnsFlushResolverCache的代码如下所示:

BOOL __stdcall DnsFlushResolverCache()
{
    BOOL bRet = FALSE;
    typedef BOOL (WINAPI *PfuncDnsFlushResolverCache)(VOID);
    HMODULE hDnsModule = LoadLibrary( _T("dnsapi.dll") );
    if ( hDnsModule != NULL ) 
    {
        PfuncDnsFlushResolverCache pFlushFun = GetProcAddress( hDnsModule, "DnsFlushResolverCache" );
        if ( pFlushFun != NULL )
        {
            pFlushFun();
            bRet = TRUE;
        }
        FreeLibrary( hDnsModule );
    }
    return bRet;
}

这样我们在软件登录服务器失败时,可以尝试自动清理一下缓存,然后重新发起登录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1627833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构---线性表(顺序表)附代码

目录&#xff1a; 数据结构相关概念 1、什么是数据结构&#xff1f; 2、为什么需要数据结构&#xff1f; 顺序表 1、顺序表的概念及结构 1.1 线性表 1.2 顺序表 2、顺序表分类 3、动态顺序表的实现 什么是数据结构&#xff1f;&#xff1f; 数据结构是由 “数据”和 …

Redis高级篇详细讲解

0.今日菜单 Redis持久化【理解】 Redis主从 Redis哨兵 Redis分片集群【运维】 单点Redis的问题 数据丢失问题&#xff1a;Redis是内存存储&#xff0c;服务重启可能会丢失数据 并发能力问题&#xff1a;单节点Redis并发能力虽然不错&#xff0c;但也无法满足如618这样的高…

用不了ChatGPT?快试试免费又强大的Anthropic Claude

一、Claude 简介 Anthropic 官方&#xff1a; https://www.anthropic.com/product Claude 是最近新开放的一款 AI 聊天机器人&#xff0c;是世界上最大的语言模型之一&#xff0c;比之前的一些模型如 GPT-3 要强大得多&#xff0c;因此 Claude 被认为是 ChatGPT 最有力的竞争…

C语言:一维数组、二维数组、字符数组介绍

数组 介绍一维数组定义应用方法初始化 举例示例结果 二维数组定义应用方法初始化 举例示例结果 字符数组定义应用方法初始化 举例示例结果分析 介绍 在C语言中&#xff0c;数组是一种基本的数据结构&#xff0c;用于存储一系列相同类型的数据。数组可以是多维的&#xff0c;最…

助力企业挖掘市场商机,赛盈分销与UseePay联合举办家居用品DTC品牌出海峰会!

随着中国经济的井喷式发展以及政策的扶持与完善下&#xff0c;中国家居品牌在全球市场上的实力不断被夯实&#xff0c;国内家居品牌数量不仅激增&#xff0c;商品也更加深远持久影响着海外消费者的生活。 中国家居企业出海之路曾陷入危机当中&#xff0c;而2023年年终的经济复苏…

多行Textview 计算切分后的长度,并回退长度

实现类似的效果&#xff0c;一个多行的 textview&#xff0c; 如果赋值一个超长的字符&#xff0c;尾部长度回退部分&#xff0c;并添加 ... 最后添加一个详情按钮。 如果不超长则不显示详情 效果如图&#xff1a; 获取截断之后的字符长度 fun getLimitedCharacterCount(textV…

微信小程序:9.小程序配置

全局配置文件 小程序根目录下的app.json文件是小程序的全局配置文件。 常用的配置文件如下: pages 记录当前小程序所有的页面存放路径信息 window 全局设置小程序窗口外观 tabBar 设置小程序底部的tabBar效果 style 是否启用新版style 小程序窗口的组成部分 了解windo节点常…

NAT网络地址转换实验(思科)

华为设备参考&#xff1a;NAT网络地址转换实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 NAT&#xff08;Network Address Translation&#xff09;&#xff0c;即网络地址转换技术&#xff0c;是一种在现代计算机网络中广泛应用的技术&#xff0c;主要用于有效管…

2024.4.26——LeetCode 高频题复盘

目录 3. 无重复字符的最长子串206. 反转链表146. LRU 缓存215. 数组中的第K个最大元素25. K 个一组翻转链表15. 三数之和53. 最大子数组和21. 合并两个有序链表1. 两数之和5. 最长回文子串912. 排序数组 3. 无重复字符的最长子串 题目链接 class Solution:def lengthOfLongest…

OV SSL证书申请指南——六步轻松搞定

OV证书的申请流程如下&#xff1a; 一 确定申请渠道 根据自己的品牌偏好&#xff0c;选择一个证书服务商&#xff0c;这里推荐JoySSL,作为国产服务商&#xff0c;除了提供Digicert、Sectigo、Geotrust、Globalsign等国际品牌证书外&#xff0c;还拥有自主品牌OV证书。在JoySSL…

Linux报错处理:‘abrt-cli status’ timed out

最近登录服务器时出现报错&#xff0c;后来查阅资料发现是因为ssh登录时间很久&#xff0c;登录后出现abrt-cli status timed out 的报错。 1.问题分析 abrt-cli是ABRT(Automated Bug Reporting Tool)的命令行接口&#xff0c;用于在Linux系统中处理和报告程序崩溃。 如果abr…

C语言笔试题之重排链表

重排链表 实例要求 1、给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln2、请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …3、不能只是单纯的改变节点内部的值&#xff0c;而是…

Java八种包装类、常量池

文章目录 一、八种基本数据类型及其包装类1.1 类型详解1.2 基本类型与包装类型相互转换——自动装箱拆箱 二、Java常量池三、包装类的常量池技术&#xff08;缓存池&#xff09;3.1 各包装类缓冲池范围3.2 Integer i1new Integer(5) 与 Integer i25 的区别3.3 Integer.valueOf(…

ADOP带您科普什么是单纤双向BiDi光模块?一根光纤,双向通信:单纤双向模块的革命性技术。

单纤双向光模块&#xff08;也称为BiDi光模块&#xff09;是一种使用WDM&#xff08;波分复用&#xff09;双向传输技术的光模块&#xff0c;它在一根光纤上实现了同时进行光通道内的双向传输。相比常规光模块&#xff08;有两个光纤插孔&#xff09;&#xff0c;BiDi光模块只有…

playwright 使用

pip install playwright 是一个命令&#xff0c;用于通过 Python 的包管理工具 pip 安装 Playwright 库。Playwright 是一个用于端到端网页测试的库&#xff0c;支持多种浏览器&#xff0c;包括 Chromium、Firefox 和 WebKit。 执行 pip install playwright 命令后&#xff0c…

SCSS全局配置 vue项目(二)

目录 1、先要查看node版本 2、安装对应的node-sass、sass-loader版本 2.1根据项目使用的node版本安装对应的node-sass版本 2.2根据node-sass版本选择兼容的sass-loader版本&#xff0c;不然项目无法正常运行 3、在 vue.config.js 中配置&#xff1a; 4、在组件中…

全志ARM-官方库SDK安装和验证

进入界面&#xff0c;输入以下指令 git clone https://github.com/orangepi-xunlong/wiringOP //下载源码 cd wiringOP //进入文件夹 sudo ./build clean //清除编译信息 sudo ./build …

Kubernetes - CentOS7搭建k8s_v1.18集群高可用(kubeadm/二进制包部署方式)实测配置验证手册

Kubernetes - CentOS7搭建k8s集群高可用&#xff08;kubeadm/二进制包部署方式&#xff09;实测配置验证手册 前言概述&#xff1a; 一、Kubernetes—k8s是什么 Kubernetes 这个名字源于希腊语&#xff0c;意为“舵手“或”飞行员"。 Kubernetes&#xff0c;简称K8s&#…

​解析什么是物联网接入网关?-天拓四方

随着物联网技术的飞速发展&#xff0c;越来越多的设备、传感器和系统被连接到互联网&#xff0c;形成了一个庞大的、相互连接的智能网络。在这个网络中&#xff0c;物联网接入网关扮演着至关重要的角色&#xff0c;它不仅是连接物联网设备和云平台的桥梁&#xff0c;还是实现设…

iOS——NSCache

什么是NSCache NSCache是Foundation框架中的一个类&#xff0c;用于在iOS和macOS应用程序中进行临时性的内存缓存。它提供了一种轻量级的缓存机制&#xff0c;可以用于存储临时性的数据&#xff0c;例如图片、对象等。NSCache的主要特点和用法包括&#xff1a; 临时性缓存&…