Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

面试官:DNS协议 是什么?说说DNS 完整的查询过程? #144

Open
linwu-hi opened this issue Jul 30, 2023 · 0 comments
Open

面试官:DNS协议 是什么?说说DNS 完整的查询过程? #144

linwu-hi opened this issue Jul 30, 2023 · 0 comments
Labels

Comments

@linwu-hi
Copy link
Owner

linwu-hi commented Jul 30, 2023

面试官:DNS协议及完整的查询过程

一、DNS协议是什么?

DNS(Domain Name System),域名系统,是互联网中的一项服务,用于将域名(例如www.example.com)解析为对应的IP地址(例如192.0.2.1)。DNS相当于一个翻译官,负责将人类可读的域名翻译成计算机可理解的IP地址,从而实现网络通信。

在计算机网络中,数据通信的核心是IP地址,但是IP地址是一串数字,不方便人们记忆和使用。因此,DNS就像一个电话簿一样,通过域名来查找相应的IP地址,使得人们可以使用便于记忆的域名来访问网站,而不必记住复杂的IP地址。

二、域名结构

域名是一个具有层次结构的标识系统,由一系列以点分隔的名字组成。从右向左,域名的层级结构由低级到高级,例如:www.example.com,其中.com为顶级域名,example为二级域名,www为三级域名。

域名系统的结构如下图所示:

. (根域名)
|
|-- com (顶级域名)
|   |
|   |-- example (二级域名)
|       |
|       |-- www (三级域名)
|           |
|           |-- ... (更多子域名)
|
|-- net (顶级域名)
|   |
|   |-- ...
|
|-- org (顶级域名)
|   |
|   |-- ...
|
... (更多顶级域名)

三、DNS查询的方式

DNS查询的方式有两种:

1. 递归查询

递归查询是一种由客户端向DNS服务器发起的查询方式,客户端会一直迭代查询直至得到最终的查询结果。在递归查询中,如果目标DNS服务器不知道某个域名的IP地址,它会向其他DNS服务器发起请求,直到找到能够解析该域名的DNS服务器为止。

2. 迭代查询

迭代查询是一种DNS服务器之间的查询方式,DNS服务器之间会相互请求信息,但不会一直迭代查询直至得到最终结果。每个DNS服务器只会返回下一级的DNS服务器地址给客户端,让客户端继续查询。

四、域名缓存

DNS查询过程中,为了减少查询时间和减轻DNS服务器负担,会在客户端和DNS服务器上设置缓存。查询过的域名和对应的IP地址会被缓存一段时间,以便下次查询时可以直接使用缓存结果,加快查询速度。

客户端和DNS服务器的缓存分别为:

  • 浏览器缓存:浏览器在获取网站域名的实际IP地址后会对其进行缓存,减少网络请求的损耗。

  • 操作系统缓存:操作系统的缓存其实是用户自己配置的 hosts 文件,可以手动添加一些常用域名和对应的IP地址,避免每次都进行DNS查询。

五、完整的DNS查询过程

下面是一个完整的DNS查询过程:

  1. 首先搜索浏览器的DNS缓存,如果存在目标域名的缓存结果,则直接返回IP地址,查询结束。

  2. 如果浏览器缓存中没有目标域名的结果,继续搜索操作系统的DNS缓存,如果存在目标域名的缓存结果,则直接返回IP地址,查询结束。

  3. 如果操作系统缓存中没有目标域名的结果,将域名发送给本地域名服务器。

  4. 本地域名服务器首先搜索自己的缓存,如果存在目标域名的缓存结果,则直接返回IP地址,查询结束。

  5. 如果本地域名服务器的缓存中没有目标域名的结果,本地域名服务器会按照递归查询的方式,向更高级的DNS服务器发起请求。

  6. 递归查询中,如果某个DNS服务器无法解析目标域名,则该DNS服务器会向更高级的DNS服务器请求解析结果,直至找到能够解析目标域名的DNS服务器。

  7. 最终,本地域名服务器得到目标域名对应的IP地址,并将IP地址返回给操作系统,并缓存该结果。

  8. 操作系统将IP地址返回给浏览器,并缓存该结果。

  9. 浏览器得到目标域名对应的IP地址,开始与服务器建立连接,进行后续的网络通信。

整个DNS查询过程涉及多个级别的DNS服务器的协作和查询,直至找到目标域名对应的IP地址。

六、DNS查询过程中的代码示例

const dns = require('dns');

function dnsLookup(domain) {
  return new Promise((resolve, reject) => {
    dns.lookup(domain, (err, address, family) => {
      if (err) {
        reject(err);
      } else {
        resolve(address);
      }
    });
  });
}

const domainName = 'www.example.com';
dnsLookup(domainName)
  .then(ipAddress => {
    console.log(`The IP address of ${domainName} is ${ipAddress}`);
  })
  .catch(error => {
    console.error(`DNS lookup failed: ${error.message}`);
  });

在这个示例中,我们定义了一个dns_lookup函数来进行DNS查询,传入域名作为参数,然后使用socket.gethostbyname()函数来获取域名对应的IP地址。如果查询失败,会捕获socket.gaierror异常,并返回相应的错误信息。

参考文献

@linwu-hi linwu-hi added the HTTP label Jul 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant