DNS协议

DNS服务器

人类更喜欢记忆主机名,而路由器更喜欢定长的、有结构层次的IP地址,DNS应运而生:DNS能进行主机名到IP地址转换的目录服务。


DSN是:
(1)一个由分层的DNS服务器(DNS server)实现的分布式数据库
(2)一个使得主机能够查询分布式数据库的应用协议

  • DNS服务器通常是运行BIND软件的UNIX机器;
  • DNS协议运行在UDP之上,使用53号端口
  • DNS通常使用UDP。

除了主机名到IP地址的转换,DNS还提供了以下非常重要的服务:(84)
(1)主机别名(host aliasing) —— 对应规范主机名(canonical hostname)
(2)邮件服务器别名(mail server aliasing)—— 对应邮件服务器的规范主机名
注:MX记录允许一个邮件服务器和Web服务器使用相同(别名化)的主机名;
(3)负载分配(load distribution)

DNS的服务由分布在全球的大量DNS服务器以及定义了DNS服务器与查询主机通信方式的应用层协议组成。

域名级别
在这里插入图片描述

  • . 代表根域名
  • .com代表顶级域名,也叫一级域名
  • baidu.com叫二级域名
  • www.baidu.com是三级域名

⭐资源记录 RR(Resource Record)

RR提供了主机名到IP地址的映射;
RR是一个包含了以下字段的四元组:(Name(域名),Value(IP),Type(记录类型),TTL(缓存时限))

TTL(Time To Live):该记录的生存时间,它决定了给了该记录应当从缓存中删除的时间;
而Name和Value的值取决于Type;

⭐RR四元组中Type的常见类型 :
(1)A : Name是主机名,Value是该主机对应的IP地址 —— 一条A类型的资源记录提供了标准主机名到IP地址的映射;
例:(relay1.bar.foo.com, 145.37.93.126, A,TTL)

(2)NS :Name是个域(如foo.com),Value是一个权威DNS服务器的主机名,该权威DNS服务器知道如何获得该域(即Name)中主机的IP地址 —— 一条NS类型的RR用于沿着查询链路来路由DNS查询;
例:(foo.com, dns.foo.com, NS, TTL)

(3)CNAME:Name为某主机的别名,Value为对应的规范主机名 —— 一条CNAME类型的RR能够提供一个主机名对应的规范主机名;
例:(foo.com, relay1.bar.foo.com, CNAME, TTL)

(4)MX: Name为某邮件服务器的别名,Value对应其邮件服务器的规范主机名 —— 一条MX类型的RR能够提供一个邮件服务器对应的规范主机名;
例:(foo.com, mail.bar.foo.com, MX, TTL)

(5)PTR:反向解析 —— 从IP到主机名

DNS通常是由其他应用层协议使用的,包括HTTP,SMTP,FTP;
但是DNS本身也属于应用层协议,因为它是使用C/S模式(客户-服务器模式)运行在通信的端系统之间的。

⭐DNS的设计模式

(1)因特网只是用一个DNS服务器:

问题包括:单点故障、通信容量、远距离的集中式数据库、维护

(2)分布式、层次数据库

当今的DNS设计模式。为了处理拓展性的问题,DNS使用了大量以层次方式组织并分布于全球范围的大量DNS服务器。没有一台DNS服务器拥有因特网上所有主机的映射,相反,这些映射分布于所有的DNS服务器上。

⭐DNS服务器分类

  • 一、根域名服务器——根DNS

    LDNS没有任何缓存,就去问根DNS,根能告诉LDNS下一步该问谁。 全球有400多个根DNS服务器,由13个组织管理,10个在美国,英国和瑞典各1个,日本1个。

  • 二、权威DNS服务器

    负责对请求作出权威的回答

    权威DNS中存储着资源记录(Resource Record),最常见的3种:A记录(记录某域名和其IP的对应),NS记录(记录某域名和负责解析该域的权威DNS),CNAME记录(负责记录某域名及其别名)。

    ① 权威能直接回答的,就回A记录;

    ② 需要其他权威DNS回答的,就回NS记录,然后LDNS再去找其他权威DNS问;

    ③ 如果该记录是别名类型的,就回CNAME,LDNS就会再去解析别名。

  • 三、TLD,顶级域名DNS服务器(Top-Level Domain)
    常见的顶级域名:com,org,net,edu,gov ; 国家顶级域名:uk,fr,jp,ca;

还有严格来说不属于上述DNS服务器层次结构的一类很重要的DNS服务器:

本地域名服务器LDNS(local DNS server)

每个ISP(如一个居民区的ISP或一个机构的ISP)都有有一台本地DNS服务器;

主机发出DNS请求时,该请求先被发往本地DNS服务器,它起着代理的作用,并将请求转发到DNS服务器层次结构中

DNS工作方式

⭐在不考虑DNS缓存的角度上,假定一个DNS客户要获取www.amazon.com的IP地址,它需要经历以下层次:

(1)与根服务器之一联系,它将返回顶级域名com的TLD服务器的IP地址
(2)与这些TLD服务器之一联系,它将返回amazon.com的权威服务器的IP地址
(3)最后,与amazon.com的权威服务器之一联系,获取www.amazon.com的IP地址

⭐一个主机通过DNS获取指定主机名对应的IP地址并发起HTTP的TCP连接的过程:

(1)浏览器截取URL中的主机名字段发送给DNS应用的客户端
(2)DNS客户端向DNS服务器发送一个包含主机名的请求
(3)DNS客户端收到来自DNS服务器发出的回答报文,该报文中包含对应请求主机名对应的IP地址
(4)浏览器接收到来自DNS的该IP地址
(5)浏览器向位于该IP地址80端口的HTTP服务器进程发起一个TCP连接

可以看到DNS的使用带来了额外的时延,但通过DNS缓存技术和其分布式、层次数据库的特性,想获得的IP地址通常就缓存在“附近的”DNS服务器中,减少了DNS的网络流量和DNS的平均时延。

⭐DNS的迭代与递归查询
理论上任何DNS查询既可以是迭代的也可以是递归的,但实践中:

(1)从请求主机到本地DNS服务器的查询是递归的——以自己的名义请求获得映射
(2)其余的查询都是迭代的——所有的回答都直接返回给本地DNS服务器

⭐DNS缓存

  • 当某DNS服务器接收到一个DNS回答,它能将映射缓存在本地DNS服务器的存储器中。

  • 但这种缓存并不是永久的,DNS服务器在一段时间后(通常为两天)将丢弃缓存信息。

  • 因为有了缓存,除了少数DNS查询以外,根服务器都被绕过了(DNS服务器也可以缓存TLD服务器的IP地址)。

⭐ 具体过程:

  • 权威DNS:权威能直接回答的,就回ip;需要其他权威DNS回答的,就回NS记录(记录某域名和负责解析该域 的权威DNS),然后LDNS再去找其他权威DNS问;如果该记录是别名类型的,就回CNAME(负责记录某域名 及其别名),LDNS就会再去解析别名。
  • 递归DNS:通常就是LDNS,它接受终端的域名查询请求,负责在网上问一圈后,将答案返回终端

以访问 www.baidu.com为例:

  1. LDNS本地没有记录,则询问根DNS
  2. 根DNS会返回顶级域名com的DNS名字与IP(NS记录)
  3. LDNS询问com的权威DNS,返回baidu.com的权威DNS名字与IP(NS)
  4. LDNS询问baidu.com的权威DNS,返回对应www.baidu.com的IP地址(A记录或者给出别名继续询问)
  5. LDNS返回终端
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
DNS(Domain Name System)协议是一种用于将域名解析为IP地址的协议,它是互联网中最重要的基础设施之一。在Java中,我们可以使用 InetAddress 类来实现 DNS 协议的模拟。 使用 InetAddress 解析域名 Java 提供了 InetAddress 类来实现 DNS 协议的解析。通过 InetAddress 类,我们可以将一个域名解析为 IP 地址。 例如: ```java String domainName = "www.baidu.com"; InetAddress[] addresses = InetAddress.getAllByName(domainName); for (InetAddress address : addresses) { System.out.println(address.getHostAddress()); } ``` 这个例子会输出百度的所有 IP 地址。 使用 DatagramSocket 发送 DNS 请求 DNS 请求是通过 UDP 协议发送的,我们可以使用 Java 的 DatagramSocket 类来发送 DNS 请求。 例如: ```java String domainName = "www.baidu.com"; byte[] requestData = new byte[1024]; InetAddress dns = InetAddress.getByName("8.8.8.8"); DatagramSocket socket = new DatagramSocket(); DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length, dns, 53); // 构造 DNS 请求报文 requestData[0] = 1; // 标识一个 DNS 请求 requestData[1] = 0; requestData[2] = 0x01; // 包含一个问题 requestData[3] = 0; requestData[4] = 0; requestData[5] = 0; requestData[6] = 0; requestData[7] = 0; requestData[8] = 0; requestData[9] = 0; requestData[10] = 0; requestData[11] = 0; requestData[12] = 3; // 域名 www requestData[13] = 'w'; requestData[14] = 'w'; requestData[15] = 'w'; requestData[16] = 5; // 域名 baidu requestData[17] = 'b'; requestData[18] = 'a'; requestData[19] = 'i'; requestData[20] = 'd'; requestData[21] = 'u'; requestData[22] = 3; // 域名 com requestData[23] = 'c'; requestData[24] = 'o'; requestData[25] = 'm'; requestData[26] = 0; // 结束符 // 发送 DNS 请求报文 socket.send(requestPacket); // 接收 DNS 响应报文 byte[] responseData = new byte[1024]; DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length); socket.receive(responsePacket); // 处理 DNS 响应报文 // ... ``` 这个例子会发送一个 DNS 请求到 Google 的 DNS 服务器(IP 地址为 8.8.8.8),请求解析百度的域名。我们构造了一个 DNS 请求报文,并使用 DatagramSocket 发送它。接着,我们等待 DNS 响应报文的到来,并处理它。 注意:这个例子中构造的 DNS 请求报文是比较简单的,真实的 DNS 请求报文可能会更加复杂。在实际使用中,我们应该使用专业的 DNS 库来发送和处理 DNS 请求和响应。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狱典司

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值