从本系列文章开始将围绕着“往浏览器输入网址后发生了什么”介绍计算机网络的相关基础知识。
本文将介绍往浏览器中输入一个网址后客户端如何封装http消息和发送dns请求查询目标主机的ip的过程。
一、客户端(如浏览器)解析url
url的组成部分如下所示:
客户端会按照 协议、域名、文件路径以及请求参数 对url进行解析(就是解析出以上信息)。
url如果没有以/结尾表示访问一个指定文件,以/结尾表示访问指定目录下的默认文件,例如:
二、生成http请求消息
解析完url后,客户端会根据请求的类型(这里以GET和POST为例)生成http请求消息。http请求消息和响应消息如下所示:
PS:get请求没有消息体,post才有。
如下为get和post请求报文格式:
客户端会根据上述(a)的格式生成http消息。
头信息列举
通用头:
请求头:
响应头:
响应消息中的状态码概述:
三、向DNS服务器查询域名对应IP
客户端生成http消息后会委托操作系统将消息发送给web服务器。操作系统拿到http报文后为了将其发送给web服务器,会先根据域名查询目标主机的IP地址。
1.简单了解IP相关知识
在网络中,所有设备都会被分配一个IP地址,IP地址相当于是服务器的坐标,客户端得知这个坐标才能将消息发送到服务器主机。
实际的IP是一串32比特的数字(IPv4标准),并按8比特分为4组,每组用原点隔开,每组以十进制表示。除了IPv4标准外还有IPv6标准,IPv6下的IP地址则是128比特的长度用于支持更多可能的地址,这里只介绍IPv4下的内容。
IP地址分为网络号和主机号两部分,网络号代表主机所在的子网网络,子网与子网间通过路由器和集线器连接和通信,主机号代表某台主机在子网中的具体位置。
IP地址被分为A~E类,每类的网络号和主机号长度是不定的,例如C类IP的前3个字节是网络号,第4个字节是主机号;而B类IP地址前2个字节是网络号,后两个字节是主机号。
IP地址会用附加信息来表示哪部分是IP的网络号,哪部分是IP的主机号。这个附加信息就是子网掩码。子网掩码是一串与IP长度相同的32比特数字,也分为主机号和网络号,其中左边一半全为1,右边一半全为0,全为1的部分为网络号,全为0的部分为主机号。
例如:10.11.12.13/255.255.255.0中255.255.255.0就是子网掩码,它的前3字节是1,第四字节为0,因此表示10.11.12.13中前3字节是网络号,第4字节是主机号。
此外还可以用 网络号比特数 表示子网掩码,如24。24表示前三字节为网络号(8*3),16表示前两个字节为网络号(8*2),8表示只有第一个字节是网络号。
域名也代表某一服务器的地址,但域名的使用是为了方便人类的记忆,而IP才是服务器所在主机的真正位置。
回到正题。
2.关于DNS解析器
DNS解析器本质上是操作系统socket库中的一段程序,用于向dns服务器发送查询请求并获取域名对应的IP并返回给客户端。而socket库是用于调用网络功能的通用程序组件。
客户端通过DNS解析器发起dns请求的过程如下所示:
客户端(浏览器)委托操作系统调用socket库的gethostbyname()这个系统调用函数,此时用户程序(浏览器)的工作会暂停并切换到操作系统的dns解析器运行,即用户态切换到内核态。
DNS解析器根据浏览器提供的域名生成DNS查询消息(DNS查询报文)并交给操作系统中的TCP/IP协议栈,由协议栈通过网卡以UDP传输的方式发送给DNS服务器。在这里,操作系统必须得知道DNS服务器的IP,这样操作系统才该把报文发送给那个DNS服务器,而这个DNS服务器的IP是已经事先设置好的,如下所示:
而这个设置好的DNS服务器一般是距离客户端主机所在城市内不远处的一个DNS服务器,我们称之为本地DNS服务器。
发送DNS查询报文后,DNS服务器会返回对应域名的IP地址给协议栈(至于DNS服务器根据域名返回对应ip的过程会在之后介绍),并按原路返回给DNS解析器,解析器将IP写入到浏览器指定的内存地址中(从内核态切回用户态),这样当该浏览器待会再想知道这个域名的IP时就直接从用户程序内存中取即可,无需在做DNS查询。此外,操作系统和浏览器还会对这个域名与IP的映射关系做缓存,即使关闭了浏览器下次再打开并请求也无需做DNS查询请求。除非缓存时间过期。
得到IP的值的浏览器终于可以开始发送HTTP请求消息。
四、DNS报文在多个DNS服务器间的传递
当客户主机的操作系统将DNS查询报文发送给本地DNS服务器到DNS服务器返回IP给客户端主机这段期间发生了什么?这里需要介绍一下DNS查询报文的内容和DNS服务器。
1.DNS查询报文和回答报文
DNS 查询和回答报文的格式是一致的,如下所示:
报文头部的12个字节包含了一些控制信息如,报文是查询还是回答报文,回答报文中告诉客户端它访问的是否为权威DNS服务器,客户端是否希望DNS服务器提供递归查询,以及该DNS服务器是否支持递归查询,回答的RR数等。
查询报文的实体部分需要包括2个部分:要查询的域名和记录类型。
记录类型表示域名对应何种类型的记录(即告诉DNS服务器,根据传过来的域名,它应该返回什么类型的响应内容)。
dns服务器中保存着多条资源记录(RR),资源记录不只包括域名与IP的映射,但包括域名与其他信息的映射,而资源记录中保存的到底是域名与什么信息的映射取决于记录类型。
如下所示:
除了上述类型,还有其他的记录类型。感兴趣的朋友可以自行查阅。
回答报文会包含多条资源记录(RR),每条资源记录包括4个字段:(Name, Value, Type, TTL)。分别是域名,域名对应的值(如IP、权威DNS域名、邮箱域名等),记录类型,记录的有效时间。
2.域名层级
一个域名的层级从左到右依次提升,每个层级用.分开。以www.abc.com为例,com是顶级域名,com域的下一层是abc域,再下一层是www这个名字。
3.DNS服务器
DNS服务器本质是一个存储着域名与相应信息映射关系的具有层级的、分布式数据库集群。
(1) 存储着域名与相应信息映射关系
DNS服务器里面保存的数据我们称之为资源记录,如下所示:
当带有 域名、class和记录类型 的请求报文到达DNS服务器后,它会根据这3个信息从资源记录中找到这3个字段都匹配的记录返回给客户端。相当于select `响应数据` from表where `域名`="xxx" and `class`="xxx" and `记录类型`="xxx";
(2) 具有层级的、分布式数据库集群
全世界的根域DNS服务器大概有十几台。
每一台根域名服务器都知道所有顶级域名DNS服务器的域名和IP,而且不管哪一个本地域名服务器要对某个域名进行解析而自己无法解析都会首先求助于根域名服务器。
每一层DNS服务器都保存着下一层DNS服务器的所有IP地址,并且所有层级的每一台DNS服务器会保存所有根域的DNS服务器IP。这么一来就能做到在本地DNS服务器能找到根域DNS服务器IP,再从根据服务器逐层往下找到其他DNS服务器。
当某一台权威DNS服务器不能给出最后的查询回答,就会告诉请求者下一步应该找到哪个权威DNS服务器。
用户主机向本地域名服务器的查询都是采用递归查询(所以用户主机只用发出一次DNS请求即可得到想要的IP地址,其他的请求交给本地DNS服务器和其他DNS服务器即可),本地域名服务器向根域名服务器的查询通常采用迭代查询,但也可以采用递归查询。
如下图所示:
有了上面的扩展知识后,我们再来说DNS报文发送到本地DNS服务器后发生了什么:
以www.lab.glasscom.com为例:
上面这种DNS查询方式是迭代查询,每次都是由本地DNS服务器发起请求,此外还有其他查询方式如递归查询,以及直接查询DNS缓存。
下面我们看看递归查询和迭代查询的区别:
如下图展示了递归查询过程:
如下图:
下节预告: 浏览器输入一个网址发生了什么(二) TCP模块封装和传输机制
本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载者并注明出处:https://jmbhsh.com/wanjumoxing/35595.html