计算机网络(二)上网过程中,浏览器究竟干了什么?

@[toc]

我们平时冲浪的时候,浏览器从接收到我们的输入网址之后,干了什么?先下结论,主要就是以下几步:

  1. 生成HTTP请求消息。
  2. DNS服务器查询Web服务器的IP地址。
  3. 委托协议栈发送消息。

以上三步的逻辑顺序也非常好理解:

用户在浏览器中输入网址(URL)之后,浏览器首先对输入的网址进行解析,根据网址的含义生成请求消息,将用户需要哪些信息告诉Web服务器端。这就是浏览器大概干的一件事情,而这里面又有一些子模块辅助共同完成上述功能。这第一步就是生成请求消息。

接下来就是需要将消息委托操作系统向Web服务器发送请求,这里就必须告诉操作系统,接收方的IP地址,这样才能将消息发送到Web服务器端嘛。网址中包含的是Web服务器的域名,因此域名转IP地址这一个操作就要依靠一个叫做DNS服务器的东西,到这里面去查询域名对应的IP地址。这也就是第二步,向DNS服务器查询Web服务器的IP地址。

经过第二步查询到IP地址之后,就可以将消息委托给操作系统发送给Web服务器,这个委托也是有一定的规则和门道的。

上述三个步骤还能继续拆开,揉碎了:

生成HTTP请求消息

浏览器拿到网址,首先就是需要对它进行解析。网址也有很多种,我们常见的是http:开头的,还有https:这个是加密的。还有一些像ftp:file:mailto:来访问不同的服务器。相当于加一个区分嘛。也可以理解为访问时需要遵循的协议,或者说需要遵守的规则。

因为URL遵循的协议不同,想要对其解析,对应的解析方法也会有差别。已访问Web服务器为例,URL的解析可以表示为如下形式:

image

解析完这个URL之后,我们就知道我们需要的东西在Web服务器的哪个地方了。这个时候浏览器就需要http协议来访问Web服务器,毕竟要遵守规则嘛,就像开门也是需要先拿钥匙,在插入锁芯,再扭一下这样一步一步嘛。

HTTP协议定义了客户端和服务器之间交互的消息内容和步骤,固定的套路就是:对哪个文件,进行什么样的操作。对哪个文件通过URL解析就能够解析出来,这个文件,或者程序也被称作URI。进行什么样的操作可以用以下这张表来表示:

image

其中圆圈表示在该版本的规格中定义的项目,三角表示并非正式规格,而是在规格书附录(Appendix)中定义的附加功能。这里面常被用到的就是GETPOST

除此之外呢,http消息中可能还有一些表示附加信息的头字段,向Web服务器发送数据时,先发送头字段,再发送数据。Web服务器收到http消息之后就开始解析,要我做一件什么样的事情呢?之后将做成功与否和结果存放在响应消息中发送回客户端。客户端浏览器拿到响应消息之后就显示在屏幕上面了。

遵循HTTP协议之后,消息就可以生成了:

image

向DNS查询IP地址

有了HTTP消息之后,接下来我们需要委托操作系统将消息发送给Web服务器。发送之前需要查询Web服务器域名对应的IP地址,因为想要操作系统发送消息,给域名是不行的,需要给服务器端的IP地址才可以。所以我们需要根据域名查询IP地址。

IP地址是一串32比特的数字,按照8比特为一组分成4组,分别用十进制表示然后再用圆点隔开。这种格式固定的方式对计算机回比较友好,就像电话号码一样。

所以拿到域名之后,操作系统需要向DNS服务器发出查询,并接收服务器返回的响应消息。这个操作也称作域名解析,负责执行解析(resolution)这一操作的就叫解析器(resolver)。解析器的用法非常简单,调用gethostbyname函数即可:

image

解析器的内部工作流程如下所示:

image

DNS发送消息,当然也需要知道DNS服务器的IP地址,不过这个IP地址是作为TCP/IP的一个设置项目事先设置好的,不需要再去查询。

如果要访问的Web服务器已经在DNS服务器上注册,那么这条记录就能够被找到,然后其IP地址会被写入响应消息并返回给客户端。

委托操作系统发送消息

知道了Web服务器端的IP地址之后,就可以委托操作系统内部的协议栈向这个目标IP地址发送HTTP消息,HTTP消息是一种数字信息(digital data)。当然这个功能不只是说给浏览器用的,对于各种网络程序都是通用的。

要想完成这个操作,需要调用socket组件中的多个,共同来完成这样一项功能。

image

想要数据传输到另一段,我们就创建一个socket套接字,之后将套接字连接起来,形成管道。之后将数据送入管道就可以收发数据了。这个管道是由客户端发起的,但是断开可由客户端或服务器端任意一方发起。总结一下又可以分为四步:

  1. 创建套接字(创建套接字阶段):创建的时候很简单,只要调用Socket库中的socket程序组件即可。套接字创建完成后,协议栈会返回一个描述符,描述符是用来识别不同的套接字的,应用程序会将收到的描述符存放在内存中。

  2. 将管道连接到服务器端的套接字上(连接阶段):这一步操作是调用Socket库中的名为connect的程序组件来完成的。调用connect时,需要指定描述符、服务器IP地址和端口号这三个参数。IP地址是找到某台计算机,端口号是用来找到这台计算机上面的哪个套接字。这个端口号不必像DNS一样去查询,服务器上所使用的端口号是根据应用的种类事先规定好的,仅此而已。比如Web80号端口,电子邮件是25号端口。

  3. 收发数据(通信阶段):之后就是将输入送入套接字中,使用write这个程序组件来发送数据,这步操作需要指定描述符和发送数据。接下来,服务器执行接收操作,解析收到的数据内容并执行相应的操作,向客户端返回响应消息。接收消息的操作是通过Socket库中的read程序组件委托协议栈来完成的,调用read时需要指定用于存放接收到的响应消息的内存地址,这一内存地址称为接收缓冲区。

  4. 断开管道并删除套接字(断开阶段):浏览器收到响应消息之后,我们需要调用Socket库的close程序组件进入断开阶段。Web使用的HTTP协议规定,当Web服务器发送完响应消息之后,应该主动执行断开操作,因此Web服务器会首先调用close来断开连接。断开操作传达到客户端之后,客户端的套接字也会进入断开阶段。接下来,当浏览器调用read执行接收数据操作时,read会告知浏览器收发数据操作已结束,连接已经断开。浏览器得知后,也会调用close进入断开阶段。

你可能感兴趣的:(计算机网络(二)上网过程中,浏览器究竟干了什么?)