什么是域名解析?域名解析的完整流程是什么?如何清理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.mfbz.cn/a/584830.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 24.04 LTS (Noble Numbat) 正式版发布

Ubuntu 24.04 LTS (Noble Numbat) 正式版发布 Canonical 的第 10 个长期支持版本在性能工程、企业安全和开发人员体验方面树立了新标准 请访问原文链接&#xff1a;Ubuntu 24.04 LTS (Noble Numbat) 正式版发布&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。…

Pytest切换测试环境:使用hooks函数、pytest-base-url插件

Pytest切换测试环境&#xff1a;使用hooks函数、pytest-base-url插件 1.使用hooks函数2.使用pytest-base-url插件安装pytest-base-url使用 1.使用hooks函数 # conftest.py#Initialization hooks 初始化钩子: 添加自定义命令行选项 def pytest_addoption(parser):parser.addopt…

一、OSPF基础

目录 1.路由协议的优先级 2.转发原则&#xff1a;最长匹配原则 3.负载分担 4.路由备份&#xff08;浮动路由&#xff09; 5.路由协议的分类 6.动态路由 7.距离矢量路由协议&#xff08;BGP&#xff0c;RIP&#xff09; 8.链路状态路由协议&#xff08;OSPF&#xff0c;I…

Vue3框架

Vue3框架 一.使用create-vue搭建Vue3项目二.组合式API - setup选项1.setup选项的写法和执行时机2.setup中写代码的特点3. script setup 语法糖 三.组合式API - reactive和ref函数1. reactive2. ref3. reactive 对比 ref 四.组合式API - computed五.组合式API - watch1. 侦听单个…

Flutter 有什么优异特性和革命性创新之处?

Flutter 有什么优异特性和革命性创新之处? 什么是 Flutter&#xff1f; Flutter mobile app SDK是一种新的方式来构建漂亮的原生移动应用程序&#xff0c;摆脱过去常见的“千篇一律”的应用程序。用过Flutter的人都对它赞赏有加&#xff1b; 相比较其他新型系统&#xff0c…

制作场景资源的Prefab

制作骨骼模型的Prefab 现在游戏内的使用骨骼模型是通过老版的Animator去实现控制的&#xff0c;所以需要将模型切换为Animator 第一步&#xff0c;动画类型设置为Generic&#xff0c;创建Avatar 模型里面会有对应的Avatar文件 我们还需要一个Controller文件&#xff0c;用于…

VMware虚拟机下载安装教程【超详细】

推荐大佬文章&#xff1a;VMware下载安装教程(超详细)-CSDN博客 目录 一、VMware下载 二、VMware安装 一、VMware下载 1、进入VMware官网 2、点击“Products”&#xff0c;向下滑动 --> 选择“Workstation Pro” 3、向下滑动&#xff0c;找到并选择“Download VMware Wo…

numpy+matplotlib绘制玫瑰线图案

【第10次课]实验十一数据可视化及应用】 声明&#xff1a;著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 1.简答题 本实验绘制简单图形&#xff0c;要导入numpy库函数和matplotlib.pyplot子库函数: import matplotlib.pyplot as plt impor…

【介绍下Android开发环境的搭建】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

源码编译framework.jar 并成功导入android studio 开发

一、不同安卓版本对应路径 Android N/O: 7 和 8 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar Android P/Q: 9 和 10 out/soong/.intermediates/frameworks/base/framework/android_common/combined/framework.jar Android R: 11以上 out/so…

计算机考研到双非院校的性价比分析

我选择读研为自己过渡深造&#xff0c;本科期间没有做过项目和实验&#xff0c;读研期间好好搞 很多公司更加看中的是个人硬实力...双非研究生出去找工作机会也并不少&#xff0c;只要实力够&#xff0c;学历加成一下&#xff0c;机会还是非常多的 研究生的学历算是一个门槛&…

Python数据预处理1:导入与基本操作

2024/4/30 After installing the xlrd package, you should be able to read Excel files using pandas without any issues. #需要在pyCharm命令行中下载两个包 pip install pandas pip install xlrd .xls数据导入 #数据的导入 import pandas as pd #导入EXCEL表格数据 df…

前端工程化Vue使用Node.js永久设置国内高速npm镜像源

前端工程化Vue使用Node.js永久设置国内高速npm镜像源 接续上篇错误收录&#xff0c;此篇通过简单配置永久设置国内高速npm镜像源方法 1.更换新版镜像 清空npm缓存 npm cache clean --force修改回原版镜像源或直接删除配置过的镜像源 npm config set registry https://registr…

Gone框架介绍3 - 使用gone命令,自动生成Priest函数

文章目录 1. 安装辅助工具: gone2. 创建一个名为gen-code的新项目3. 创建Goner4. 使用辅助工具5. 添加main函数 我在两年前实现了一个Golang的依赖注入框架&#xff0c;并且集成了gin、xorm、redis、cron、消息中间件等功能&#xff0c;自己觉得还挺好用的&#xff1b;之前一直…

9.【Linux】(死锁问题||线程同步||条件变量||生产者消费者模型)

常见锁的概念 死锁 死锁是指在一组进程中各个进程均占有不会释放的资源&#xff0c;但因互相申请被其他进程所占用的不会释放的资源而处于一种永久等待的状态。简单来说就是两个线程都 在等待对方释放锁。 死锁必要条件 必须同时满足四个条件才会产生死锁 1.互斥条件&…

等级保护测评试题上

一、单选题 1、下列不属于网络安全测试范畴的是&#xff08;C&#xff09; A&#xff0e;结构安全 B.便捷完整性检查 C.剩余信息保护 D.网络设备防护 2、下列关于安全审计的内容说法中错误的是&#xff08;D&#xff09; A&#xff0e;应对网络系统中的网络设备运行情况、网…

陪玩线下找搭子交友小程序开源版开发

陪玩线下找搭子交友小程序开源版开发 模式是一种线上预约、线下体验的多元化社交平台。 范围广泛&#xff0c;包括电竞陪练、户外运动陪伴、音乐艺术交流、旅游伴游、生活技能指导等&#xff0c;覆盖电竞、运动、音乐、游戏、旅游、文化、艺术、学习等多个领域。 无论是亲子互…

最新游戏陪玩语音聊天系统3.0商业升级独立版本源码+搭建教程

首发价值29800元的最新商业版游戏陪玩语音聊天系统3.0商业升级独立版本源码。 下 载 地 址 &#xff1a; runruncode.com/php/19748.html 1. 新增人气店员轮播功能。 2. UI界面优化&#xff0c;包括游戏图标展示和分类展示的改进。 3. 增加动态礼物打赏功能。 4. 新增礼…

分布式与一致性协议之CAP和Paxos算法(一)

CAP 理论 如何使用BASE理论 以InfluxDB系统中DATA节点的集群实现为例。DATA节点的核心功能是读和写&#xff0c;所以基本可用是指读和写的基本可用。我们可以通过分片和多副本实现读和写的基本可用。也就是说&#xff0c;将同一业务的数据先分片&#xff0c;再以多份副本的形…

录屏功能怎么打开?这3个小技巧你得学会

当我们在使用电子设备时&#xff0c;您是否也想将屏幕上的精彩内容分享给他人&#xff0c;又或者想要记录自己的操作步骤。这时&#xff0c;录屏功能就显得尤为重要。那么&#xff0c;录屏功能怎么打开&#xff1f; 接下来&#xff0c;我将为大家详细介绍3种常见的打开录屏功能…
最新文章