《网络是怎样连接的》--- 探索浏览器的内部
- 生成HTTP请求消息
- DNS查询IP地址
- DNS工作方式
- 委托协议栈发送消息
生成HTTP请求消息
- 了解URL的地址格式
http://user:[email protected]:80/dir/file1.htm
协议类型:http ftp mailto
- 浏览器解析URL过程
浏览器会按照URL元素进行解析成©的情况
3.HTTP的基本思路
请求消息中包含的内容是“对什么”和“进行怎样的操作”两个部分
“对什么” :就是URI
“进行怎样的操作:HTTP的主要方法(GET,POST)
- 生成请求消息
对 URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息。
HTTP 消息会按照规定的格式来生成请求消息。HTTP请求消息格式:
第一部分为请求行
第二部分为消息头
第三部分为消息体
每一部分中间空行隔开
- 服务器的响应
服务器接收到请求消息后,会作出相应的消息响应,这个响应信息也有一定的格式。
在响应信息中状态码
注意:1 条请求消息中只能写 1 个 URI。如果需要获取多个文件,必须
对每个文件单独发送 1 条请求。
DNS查询IP地址
- Socket库提供查询IP地址的功能
我们的计算机上一定有相应的 DNS 客户端,而相当于 DNS 客户端的部分称为 DNS 解析器,或者简称解析器。
解析器实际上是一段程序,它包含在操作系统的 Socket 库中。
Socket 库是用于调用网络功能的程序组件集合。集合包括发送和接收的程序等。
- 通过解析器向DNS服务器发出查询
网络应用程序(这里指浏览器)调用Socket库中的组件。完成解析器的调用。
解析器会向 DNS 服务器发送查询消息,然后 DNS 服务器会返回响应消息。响应消息中包含查询到的 IP 地址,解析器会取出 IP地址,并将其写入浏览器指定的内存地址中。只需从内存中取出IP地址。
总结:根据域名查询 IP 地址时,浏览器会使用 Socket 库中的解析器。
- 解析器的内部原理
应用程序调用socket解析器,当控制流程转移到解析器后,解析器会生成要发送给 DNS 服务器的查询消息,socket解析器完成应用程序的委托操作后;解析器需要委托操作系统的内部协议栈执行,协议栈会执行发送操作,从网卡发送给DNS服务器。
- DNS’工作方式
来自DNS客户端的查询消息包含3种消息
(1)域名
服务器、邮件服务器(邮件地址中 @ 后面的部分)的名称
(2)Class
Class 的值永远是代表互联网的 IN。
(3)记录类型
表示域名对应何种类型的记录。例如:
当类型为 A 时,表示域名对应的是 IP 地址;
当类型为 MX 时,表示域名对应的是邮件服务
器。对于不同的记录类型,服务器向客户端返回的信息也会不同
服务器会根据者三种信息返回对应的记录
总结:DNS 服务器会从域名与 IP 地址的对照表中查找相应的记录,并返回 IP 地址。
- 域名的层次结构
比如 www.lab.glasscom.com 这个域名如果按照公司里的组织结构来说,大概就是“com 事业集团 glasscom 部 lab 科的 www”这样。其中,相当于一个层级的部分称为域。
因此,com 域的下一层是glasscom 域,再下一层是 lab 域,再下面才是 www 这个名字。
一个域的信息是作为一个整体存放在 DNS 服务器中的,不能将一个域拆开来存放在多台 DNS 服务器中。可以在域下拆分:example.co.jp,我们可以在这个域的下面创建两个子域,即 sub1.
example.co.jp 和 sub2.example.co.jp。
DNS服务器和域可以是一对一、一对多的关系。
- 寻找相应的 DNS 服务器并获取 IP 地址
DNS目录结构,如 www.lab.glasscom.com.
根域“.",下级域”com",下级“glasscom”…
客户端首先会访问最近的一台 DNS 服务器,
假设我们要查询 www.lab.glasscom.com 这台 Web 服务器的相关信息(图 1.16 ①)。由于最近的 DNS 服务器中没有www.lab.glasscom.com 这一域名对应的信息,
所以我们需要从顶层开始向下查找。最近的 DNS 服务器中保存了根域 DNS 服务器的信息,因此它会将来自客户端的查询消息转发给根域 DNS 服务器(图 1.16 ②)。
根域服务器中也没有 www.lab.glasscom.com 这个域名,但根据域名结构可以判断这个域名属于 com 域,因此根域 DNS 服务器会返回它所管理的 com 域中的DNS 服务器的 IP 地址,去查找com 域。
接下来,最近的 DNS 服务器又会向 com 域的
DNS 服务器发送查询消息(图 1.16 ③)。com 域中也没有 www.lab.glasscom.com这个域名的信息,和刚才一样,com 域服务器会返回它下面的 glasscom.com域的 DNS 服务器的 IP 地址。
以此类推,只要重复前面的步骤,就可以顺藤摸瓜找到目标 DNS 服务器(图 1.16 ⑤),只要向目标 DNS 服务器发送查询消息,就能够得到我们需要的答案,也就是 www.lab.glasscom.com 的 IP 地址了。
- DNS缓存
为了加快响应速度,进行DNS缓存,并会定期删除缓存,保证信息正确。
委托协议栈发送消息
- 总览
知道DNS服务器得到ip地址后,需要委托操作系统内部的协议栈向这个目标 IP地址,发送 HTTP 消息(是一种数字信息(digital data)),因此也可以说是委托协议栈来发送数字信息。
向操作系统内部的协议栈发出委托时,需要按照指定的顺序来调用 Socket 库中的程序组件。
收发消息端连接一条数据通道。通过这条假象的管道通信。
建立管道的关键在于管道两端的数据出入口,这些出入口称为套接字
首先,服务器一方先创建套接字,进入等待状态。客户端也会先创建一个套接字,然后从该套接字延伸出管道,最后管道连接到服务器端的套接字上。当双方的套接字连接起来之后,通信准备就完成了。
四点:
(1)创建套接字(创建套接字阶段)
(2)将管道连接到服务器端的套接字上(连接阶段)
(3)收发数据(通信阶段)
(4)断开管道并删除套接字(断开阶段)
前面这 4个操作都是由操作系统中的协议栈来执行的。socket组件只是桥梁作用。
- 创建套接字
套接字创建完成后,协议栈会返回一个描述符,应用程序会将收到的描述符存放在内存中。描述符是用来识别不同的套接字的。
- 连接阶段:把管道接上去
应用程序通过调用 Socket 库中的名为 connect 的程序组件来完成这一操作。这里的要点是当调用 connect 时,需要指定描述符、服务器 IP 地址和端口号这 3 个参数。
(1)描述符: connect 会将应用程序指定的描述符告知协议栈,然后协议栈根据这个描述符来判断到底使用哪一个套接字去和服务器端的套接字进行连接,并执行连接的操作。
(2)服务器 IP 地址
(3)端口号:能够指定找到我们的套接字。当同时指定 IP 地址和端口号时,就可以明确识别出某台具体的计算机上的某个具体的套接字。
总而言之,就是当调用 connect 时,协议栈就会执行连接操作。当连接成功后,协议栈会将对方的 IP 地址和端口号等信息保存在套接字中
- 通信阶段
应用程序无法直接控制套接字,因此还是要通过 Socket 库委托协议栈来完成这个操作,通过write组件。
当调用 write 时,需要指定描述符和发送数据,然后协议栈就会将数据发送到服务器。
接收消息的操作是通过 Socket 库中的 read 程序组件委托协议栈来完成的。调用 read 时需要指定用于存放接收到的响应消息的内存地址(即接收缓冲区)存放消息。
- 断开阶段
需要调用 Socket 库的 close 程序组件进入断开阶段最终,连接在套接字之间的管道会被断开,套接字本身也会被删除。
总结:浏览器与 Web 服务器之间收发消息的过程,但实际负责收发消息的是协议栈、网卡驱动和网卡。