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

目录

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、域名解析的完整流程

       当软件使用域名访问远端的服务器时,软件内部会先将域名转换成IP地址,然后通过IP地址去连接远端的服务器,然后再和远端的服务器进行数据交互。将域名转换成IP地址的过程,就称为域名解析。

为啥域名要转换成IP地址后才能访问远端的服务器呢?其实很好理解,软件是通过网络和远端的服务器进行交互的。从TCPIP的分层模型来看:

域名属于应用层的概念(解析域名所使用的DNS协议,也属于应用层的协议),而进入到网络层,则需要使用IP路由去寻找远端的服务器,IP路由肯定要使用到IP地址,所以应用层需要事先将域名转换成IP地址后,使用IP地址去连接远端的服务器。

       在进行域名解析时,底层会使用专用的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.mzph.cn/news/829619.shtml

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

相关文章

PeLK: 大卷积核强势回归,高达101 × 101,提出了外围卷积

paper&#xff1a;https://arxiv.org/pdf/2403.07589 code&#xff1a;暂无 目录 0. 摘要 1. 引言 2. 相关工作 2.1. Large Kernel Convolutional Networks 2.2. Peripheral Vision for Machine Learning 3. 密集卷积优于条纹卷积 4. 参数高效的大核卷积神经网络 4.1. …

粒子群算法与优化储能策略python实践

粒子群优化算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;, 是1995年J. Kennedy博士和R. C. Eberhart博士一起提出的&#xff0c;它是源于对鸟群捕食行为的研究。粒子群优化算法的基本核心是利用群体中的个体对信息的共享从而使得整个群体的运动…

基于 Redis 发布订阅实现服务注册与发现

写在前面 其实很少有公司会使用 Redis 来实现服务注册与发现&#xff0c;通常是ETCD、NACOS、ZOOKEEPER等等&#xff0c;但是也不妨碍我们了解。本文会先介绍 Redis 的发布/订阅模式&#xff0c;接着基于这个模式实现服务注册与发现。 Redis发布订阅流程图&#xff1a; Red…

云备份项目->配置环境

升级gcc到7.3版本 sudo yum install centos-release-scl-rh centos-release-scl sudo yum install devtoolset-7-gcc devtoolset-7-gcc-c source /opt/rh/devtoolset-7/enable echo "source /opt/rh/devtoolset-7/enable" >> ~/.bashrc 安装Jsoncpp库 sud…

MyBatis面试题总结,详细(2024最新)

面试必须要看看 1、MyBatis 中的一级缓存和二级缓存是什么&#xff1f;它们的区别是什么&#xff1f; MyBatis 中的一级缓存是指 SqlSession 对象内部的缓存&#xff0c;它是默认开启的。一级缓存的生命周期是与 SqlSession 对象绑定的&#xff0c;当 SqlSession 关闭时&#…

Linux--进程控制(2)--进程的程序替换(夺舍)

目录 进程的程序替换 0.相关函数 1.先看现象 2.解释原理 3.将代码改成多进程版 4.使用其它的替换函数&#xff0c;并且认识函数参数的含义 5.其它 进程的程序替换 0.相关函数 关于进程替换我们需要了解的6个函数&#xff1a; 函数解释&#xff1a; 这些函数如果调用成功则…

通过filebeat实现对docker服务的通用日志收集

平台 依赖 linux docker docker-compose 或者 docker compose 镜像 docker.elastic.co/beats/filebeat:8.12.2 docker.elastic.co/beats/kibana:8.12.2 docker.elastic.co/beats/elasticsearch:8.12.2 正文 背景 对于有自建机房的公司来说&#xff0c;如果公司的运维技术…

Stable Diffusion使用ControlNet:IP-Adapter实现图片风格迁移

IP-Adapter 全称是 Text Compatible Image Prompt Adapter for Text-to-Image Diffusion Models&#xff08;文本到图像扩散模型的文本兼容图像提示适配器&#xff09;&#xff0c;是腾讯研究院出品的一个新的ControlNet模型&#xff0c;旨在使预训练的文本到图像扩散模型能够生…

【06】JAVASE-数组讲解【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture&#xff1a;波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。…

最全GPTs使用教程+Prompt预设词教程

使用指南 直接复制使用 可以前往已经添加好Prompt预设的AI系统测试使用&#xff08;可自定义添加使用&#xff09; https://ai.sparkaigf.com 现已支持GPTs 雅思写作考官 我希望你假定自己是雅思写作考官&#xff0c;根据雅思评判标准&#xff0c;按我给你的雅思考题和对应…

从零入门区块链和比特币(第三期)

欢迎来到我的区块链与比特币入门指南&#xff01;如果你对区块链和比特币感兴趣&#xff0c;但不知道从何开始&#xff0c;那么你来对地方了。本博客将为你提供一个简明扼要的介绍&#xff0c;帮助你了解这个领域的基础知识&#xff0c;并引导你进一步探索这个激动人心的领域。…

一些基础知识FK

1. 群体稳定性指数PSI 通过 PSI(Population Stability Index) 指标&#xff0c;可以得到不同样本下&#xff0c;模型在各分数段分布的稳定性。用于衡量两个群体(比如两个时间点、两个子群体等)之间稳定性的指标。通常PSI被用于评估信用风险模型、预测模型等在不同时间点或不同群…

安装配置Maven(idea里面配置)

放在这个路径下&#xff08;如果需要可以免费发给你&#xff0c;dd我就好了&#xff09; D:\IearnSoftware\maven\apache-maven-3.6.1-bin.zip&#xff08;我自己的路径下面&#xff0c;防止忘记&#xff09; 1.首先测试maven在不在&#xff0c;配置对不对 mvn -v 这样就是成…

STM32HAL库++ESP8266+cJSON连接阿里云物联网平台

实验使用资源&#xff1a;正点原子F1 USART1&#xff1a;PA9P、A10&#xff08;串口打印调试&#xff09; USART3&#xff1a;PB10、PB11&#xff08;WiFi模块&#xff09; DHT11&#xff1a;PG11&#xff08;采集数据、上报&#xff09; LED0、1&#xff1a;PB5、PE5&#xff…

【微信小程序调用百度API实现图像识别实战】-前后端加强版

前言&#xff1a;基于前面两篇图像识别项目实战文章进行了改造升级。 第一篇 入门【微信小程序调用百度API实现图像识别功能】----项目实战 第二篇 前后端结合 【微信小程序调用百度API实现图像识别实战】----前后端分离 这一篇主要讲述的是在第二篇的基础上新增意见反馈功能&a…

第72天:漏洞发现-Web框架中间件联动GobyAfrogXrayAwvsVulmap

案例一&#xff1a;某 APP-Web 扫描-常规&联动-Burp&Awvs&Xray Acunetix 一款商业的 Web 漏洞扫描程序&#xff0c;它可以检查 Web 应用程序中的漏洞&#xff0c;如 SQL 注入、跨站脚本攻击、身份验证页上的弱口令长度等。它拥有一个操作方便的图形用户界 面&#…

实验8 NAT配置

实验8 NAT配置 一、 原理描述二、 实验目的三、 实验内容1.实验场景2.实验要求 四、 实验配置五、 实验步骤2.静态NAT配置3.NAT Outbound配置4.NAT Easy-IP配置 一、 原理描述 2019年11月26日&#xff0c;全球43亿个IPv4地址正式耗尽&#xff0c;这意味着没有更多的IPv4地址可…

Taro引入echarts【兼容多端小程序(飞书/微信/支付宝小程序)】

近期接到公司新需求&#xff0c;开发飞书小程序&#xff0c;并且原型中含有大量的图表&#xff0c;本想使用飞书内置图表组件 —— chart-space&#xff0c;但官方表示已经停止维护了&#xff0c;无奈之下&#xff0c;只能另寻他路&#xff0c;于是乎&#xff0c;图表之王&…

【Godot4.2】自定义Todo清单类 - myTodoList

概述 在写myList类的时候&#xff0c;就想到可以写一个类似的Todo清单类。 基础思路 本质还是在内部维护一个数组&#xff0c;在其基础上进行增删改查操作的封装为了方便存储数据&#xff0c;编写一个自定义内置类TodoItem&#xff0c;内部数组就变成了Array[TodoItem]类型的…

【Flutter】GetX

前言 状态管理 / 路由管理 / 依赖管理 这三部分之间存在联系 参考文章 建议看官网文章&#xff0c;很详细 &#xff0c;pub.dev搜索get pub.dev的文档 状态管理文章相关链接 状态管理 案例 实现一个计算器&#xff0c;运用GetX去管理它 构建界面 构建一个计算器界面 …