网络浏览器是如何工作的

Chrome、Firefox、Microsoft Edge等浏览器我们经常用,但它们是如何工作的?

这是一篇介绍浏览器在网络环境下的一般工作原理的文章。

一,从输入网址并按下回车开始——生成 HTTP 请求消息

1,什么是网址?

**超链接(hyperlink)**是一种允许我们同其他网页或站点之间进行连接的元素,

文本中包含内嵌超链接的话,整个文档就叫作超文本(hypertext)文档,如果文档中又加入了图片、 声音以及视频, 该文档就成为了超媒体(hypermedia)

为了操作超媒体, 人们发明了统一资源定位符(URL, Uniform Resource Locator),URL使用一个标记指明了获取文档所使用的协议。

网络浏览器本质就是一个具备多种客户端功能的综合性客户端软件, 因此它需要一些东西来判断应该使用哪种功能来访问相应的数据,这就是URL中的标记及相关信息的作用。

根据访问目标的不同,URL 的写法也会不同,常见的如下:
在这里插入图片描述
看得出来,第一个标记(如https或http )即为所使用的机制(scheme ),它指明了获取文档所使用的协议(protocal),它后面跟着规范符号,即一个冒号和两个斜杠(://),然后是主机名(host),接着可能还有端口号(port),最后是一个路径(path)。它它们组合在一起,用于在可用服务的所有文档中指明要获取的特定文档。这就是URL的结构了。

好了,以上就是我们常说的网址了。

扩展:URI、URN

2,浏览器先要解析URL

既然URL的格式会随着访问目标的不同而不同,那么在发送访问请求之前,浏览器先要解析URL

假如要访问http://www.lab.glasscom.com/dir1/file1.html,浏览器就要先根据URL的结构对URL进行切片式定位
在这里插入图片描述
在这里插入图片描述

扩展:省略文件名的情况、urllib.parse模块解析与构造URL、相对地址与绝对地址

3,HTTP请求与响应的基本思路

解析完URL之后, 浏览器就知道应该要访问的方法是什么、目标在哪里了。

马上,浏览器会使用解析出来的HTTP协议来访问Web服务器,这个协议定义了客户端和服务器之间交互的消息内容和步骤
在这里插入图片描述

首先,客户端向会服务器发送一个获取文档的请求(request)。请求消息中包含的内容是对什么进行怎样的操作两个部分。一旦发送完整个请求,客户端就会进行等待,直到接收到服务器返回的响应(response)为止。

  1. 对什么:可以通过网络访问的物理文档。
  2. 进行怎样的操作:让Web服务器完成怎样的工作。

然后,Web服务器收到请求消息之后, 会对其中的内容进行解析,并根据对什么和进行怎样的操作两个部分来完成自己的工作, 并将结果存放在响应中发送给客户端。响应中可能会包含错误信息如找不到的文件就会显示出 404 Not Found 的错误信息,还包含是状态码如 404,响应中也可能会提供客户端请求的文档信息如一个网页信息。

最后,客户端收到响应之后, 从响应的消息体中读出所需的数据。

HTTP The Definitive Guide 1: Overview of HTTP

二,域名解析——向 DNS 服务器查询 Web 服务器的 IP 地址

尽管浏览器能够解析网址并生成 HTTP 消息, 但 HTTP 协议本身并不具备将消息在网络中进行传输的功能, 而这一功能需要委托操作系统进行实现。

1,IP 地址的基本知识

就像邮局寄信一样,通信双方收发信件前需要填上详细且唯一的地址才能完成通信。在网络环境工作的机器就有这样一个唯一的地址:IP地址。

尽管你可能听过计算机网络中的OSI七层模型,但实际上,互联网和公司内部的局域网都是基于 TCP/IP模型:由路由器将小的子网连接起来组成更大的网络。
在这里插入图片描述
简单看一下消息在网络中的通信过程:

  1. 终端发送者发出的消息首先经过子网中的集线器 A,转发到距离发送者最近的路由器上。
  2. 路由器会根据消息的目的地判断下一个路由器的位置,然后将消息发送到下一个路由器,即消息再次经过子网内的集线器被转发到下一个路由器。
  3. 前面的过程不断重复,最终消息就被传送到了目的地。

既然网络就是由一级一级的子网嵌套组成的,那么,要确定计算机在网络中的位置,就首先要确定计算机在哪个子网,然后在确定的子网中再确定具体的计算机,所以,IP地址就是这样一个由网络号和主机号组成的地址。

实际的 IP 地址是一串 32 比特的数字,按照 8 比特(1 字节)为一组分成 4 组,分别用十进制表示然后再用圆点隔开。这就是我们平常经常见到的 IP 地址格式:
在这里插入图片描述

但仅凭这一串数字我们无法区分哪部分是网络号,哪部分是主机号,所以我们还需要一个被称为子网掩码的附加信息来表示 IP 地址的内部结构。
子网掩码是一串与 IP 地址长度相同的 32 比特数字。子网掩码为 1 的部分表示网络号,子网掩码为 0 的部分表示主机号。:
在这里插入图片描述
局域网里是由网络管理员来分配 IP 地址。一般上网的话,是电信接入提供商 ISP 分配。

2,IP 地址与网址

实际上,如果使用 IP 地址来代替服务器名称是能够正常工作的 。

但为什么使用服务器名称和使用 IP 地址两种方式要共同存在呢?

  • 从用户角度来看,要记住一串由数字组成的 IP 地址也非常困难。因此,相比 IP 地址来说,网址中还是使用服务器名称比较好。
  • 从TCP/IP模型角度来看,指定了规则的 IP 地址更有利于提高网络的整体性能。

为了让人来使用名称、让路由器来使用 IP 地址,就需要有一个机制能够通过名称来查询 IP 地址,或者通过 IP 地址来查询名称,这样就能够在人和机器双方都不做出太大牺牲的前提下完美地解决两种方法的沟通障碍,这个机制就是域名解析服务DNS

3,通过解析器向 DNS 服务器发出查询

查询 IP 地址的方法非常简单,只要询问最近的 DNS 服务器“www.lab.glasscom.com 的 IP 地址是什么”就可以了,DNS 服务器会回答说“该服务器的 IP 地址为 xxx.xxx.xxx.xxx”。这一步非常简单。

那么浏览器是如何向 DNS 服务器发出查询的呢?

相对于 DNS 服务器,我们的计算机上一定有相应的 DNS 客户端。通过 DNS 查询 IP 地址的操作称为域名解析,负责执行解析操作的就叫解析器(resolver)

解析器实际上是一段程序,它包含在操作系统的 Socket 库中。
库就是一堆通用程序组件的集合,其他的应用程序都需要使用其中的组件。Socket 库是用于调用网络功能的程序组件集合。

既然解析器就是一段标准的程序,那么,它的用法就非常简单,只要在应用程序中进行调用就可以了。
具体来说,在编写浏览器等应用程序的时候,写上解析器的程序名称“gethostbyname”以及 Web 服务器的域名“www.lab.glasscom.com”。
调用解析器后,解析器会向 DNS 服务器发送查询消息,然后 DNS 服务器会返回响应消息。响应消息中包含查询到的 IP 地址,解析器会取出 IP地址,并将其写入浏览器指定的内存地址中。

在这里插入图片描述
获取 IP 地址后,浏览器在向 Web 服务器发送消息时,只要从该内存地址取出 IP 地址,并将它与 HTTP 请求消息一起交给操作系统就可以了。

向 DNS 服务器发送消息时,我们当然也需要知道 DNS 服
务器的 IP 地址。只不过这个 IP 地址是作为 TCP/IP 的一个设置项目事先设置好的,不需要再去查询了。
在这里插入图片描述

三,与操作系统的进一步配合——委托协议栈发送消息

1,数据收发操作

浏览器通过 DNS 服务知道了 IP 地址之后,就可以委托操作系统内部的协议栈向这个目标 IP地址,也就是我们要访问的 Web 服务器发送消息了。

要发送给 Web 服务器的 HTTP 消息是一种数字信息(digital data),因此也可以说是委托协议栈来发送数字信息。

收发数字信息这一操作不仅限于浏览器,对于各种使用网络的应用程序来说都是共通的。因此,这一操作的过程也不仅适用于Web,而是适用于任何网络应用程序 。

使用 Socket 库来收发数据的过程:
在这里插入图片描述

我们可以把数据通道想象成一条管道,将数据从一端送入管道,数据到达管道的另一端后会被取出。
数据可以从任何一端被送入管道,且数据的流动是双向的。

显然,在正式发送HTTP 消息之前需要建立这种用于数据流动的管道。
建立管道的关键在于管道两端的数据出入口,这些出入口称为套接字。我们需要先创建套接字,然后再将套接字连接起来形成管道。

所以,整个数据收发操作的大概过程是这样的:

  1. 首先,服务器一方先创建套接字,然后等待客户端向该套接字连接管道。当服务器启动之后进入监听状态时,客户端就可以连接管道了。
  2. 客户端在发出请求前也会先创建一个套接字,然后从该套接字延伸出管道,最后管道连接到服务器端的套接字上。
  3. 当双方的套接字连接起来之后,通信准备就完成了。接下来,就只要将数据送入套接字就可以收发数据了。
  4. 当数据全部发送完毕之后,连接的管道将会被断开。管道在连接时是由客户端发起的,但在断开时可以由客户端或服务器任意一方发起。其中一方断开后,另一方也会随之断开,当管道断开后,套接字也会被删除。到此为止,通信操作结束。

在每个阶段,Socket 库中的程序组件都会被调用来执行相关的数据收发操作。而这四步操作都是由操作系统中的协议栈来执行的,浏览器等应用程序并不会自己去做连接管道、放入数据这些工作,而是委托协议栈来代劳。

2,创建套接字阶段

客户端创建套接字的操作非常简单,只要调用 Socket 库中的 socket 程序组件就可以。
调用 socket 之后,控制流程会转移到 socket 内部并执行创建套接字的操作,完成之后控制流程又会被移交回应用程序。
在这里插入图片描述

实际上,为了识别多个套接字,套接字创建完成后,协议栈会返回一个描述符,应用程序会将收到的描述符存放在内存中。只要我们出示描述符,协议栈就能够判断出我们希望用哪一个套接字来连接或者收发数据了。

3,连接管道阶段

接下来,我们需要委托协议栈将客户端创建的套接字与服务器那边的套接字连接起来。应用程序通过调用 Socket 库中的 connect 程序组件来完成这一操作。

调用 connect 时,需要指定描述符、服务器 IP 地址端口号这 3 个参数:

  • 描述符,就是在创建套接字的时候由协议栈返回的那个描述符。connect 会将应用程序指定的描述符告知协议栈,然后协议栈根据这个描述符来判断到底使用哪一个套接字去和服务器端的套接字进行连接,并执行连接的操作。
  • 服务器 IP 地址就是通过 DNS 服务器查询得到的要访问的服务器的 IP 地址。
  • 知道 IP 地址就可以识别出网络上的某台计算机,但仅仅知道要连接哪台计算机是完成不了应用程序之间的数据通信的。连接操作的对象是某个具体的套接字,因此必须要识别到具体的套接字才行,这就是而端口号的作用。

如果说描述符是用来在一台计算机内部识别套接字的机制,那么端口号就是用来让通信的另一方能够识别出套接字的机制,而且服务器上所使用的端口号是根据应用的种类事先规定好的,比如 Web 是 80 号端口,电子邮件是 25 号端口。
既然服务器上所使用的端口号是事先规定好的,那么,为了完成通信,客户端是如何确定端口号的?客户端在创建套接字时,协议栈会为这个套接字随便分配一个端口号,当协议栈执行连接操作时,会将这个随便分配的端口号通知给服务器。

当连接成功后,协议栈会将对方的 IP 地址和端口号等信息保存在套接字中,这样我们就可以开始收发数据了。

4,收发数据阶段

只要将数据送入套接字,数据就会被发送到对方的套接字中。当然,应用程序无法直接控制套接字,因此还是要通过 Socket 库委托协议栈使用write 程序组件来完成这个操作。

应用程序需要在内存中准备好要发送的数据。根据用户输入的网址生成的 HTTP 请求消息就是我们要发送的数据接着,
由于套接字中已经保存了已连接的通信对象的相关信息,所以只要通过描述符指定套接字,就可以识别出通信对象,并向其发送数据。发送数据会通过网络到达我们要访问的服务器。
服务器执行接收操作,解析收到的数据内容并执行相应的操
作,向客户端返回响应消息。

当消息被返回后,客户端需要执行的是接收消息的操作。接收消息的操作是通过 Socket 库中的 read 程序组件委托协议栈来完成的。调用 read 时需要指定用于存放接收到的响应消息的内存地址,这一内存地址称为接收缓冲区

5,断开管道阶段

当浏览器收到数据之后,收发数据的过程就结束了。接下来,我们需要调用 Socket 库的 close 程序组件进入断开阶段。最终,连接在套接字之间的管道会被断开,套接字本身也会被删除。

Web 使用的 HTTP 协议规定,当 Web 服务器发送完响应消息之后,应该主动执行断开操作,因此 Web 服务器会首先调用 close 来断开连接。
断开操作传达到客户端之后,客户端的套接字也会进入断开阶段。
接下来,当浏览器调用 read 执行接收数据操作时,read 会告知浏览器收发数据操作已结束,连接已经断开。浏览器得知后,也会调用 close 进入断开阶段。

对于同一台服务器来说,重复连接和断开显然是效率很低的,
因此,在 HTTP 1.1 版本中又设计出了能够在一次连接中收发多个请求和响应的TCP复用机制,当所有数据都请求完成后,浏览器才会主动触发断开连接的操作。
在 HTTP 2.0 中又增加了多路复用和帧的概念,通过一次TCP连接,可以把多个HTTP请求封装到不同的帧发送到服务,服务器分别对多个请求做出响应,客户端收到响应后,根据帧的标识,分别交给发起请求的不同应用程序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值