一个http请求

1.生成HTTP请求消息

当我们在访问一个网页的时候,在浏览器输入一个网址,到浏览器显示该网页,这中间发生了什么?

首先我们要介绍一下网址:

使用HTTP协议访问Web服务器:

http://www.baidu.com

使用FTP协议下载和上传文件:

ftp://ftp.glasscom.com/dir/file.htm

读取客户端计算机本地文件:

file://localhost/Users/

发送电子邮件:

mailto:[email protected]

阅读新闻组的文章:

news:comp.protocols.tcp-ip

浏览器需要先解析URL,如下图:

浏览器解析URL过程

解析完URL之后,接下来浏览器会使用HTTP协议来访问Web服务器

HTTP 协议定义了客户端和服务器之间交互的消息内容和步骤,其基本思路非常简单。首先,客户端会向服务器发送请求消息,请求消息中包含的内容是“对什么”和“进行怎样的操作”两个部分。

其中“对什么”的部分称为URI,URI的内容是一个存放网页数据的文件名或者是一个CGI 程序的文件名,例如“/dir1/file1.html”
“/dir1/program1.cgi”等。

不过,URI不仅限于此,也可以直接使用“http:”开头的URL来作为URI。

而“进行怎样的操作”的部分称为方法,方法表示需要让Web服务器完成怎样的工作。

HTTP方法

浏览器确定了Web服务器和文件名,接下来就是根据这些消息来生成HTTP请求消息,生成消息的格式如下图:

HTTP消息格式

请求消息的示例:

GET /img/bd_logo1.png?where=super HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: https://www.baidu.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

发送消息后会收到响应,响应消息的格式以及基本思路和请求消息是相同的,差别只在第一行上面

在响应消息中,第一行的内容为状态码和响应短语,用来表示请求的执行结果是成功还是出错,下图是状态码的概要:

HTTP状态码

注意:1条请求消息中只能写1个URI。如果需要获取多个文件,必须对每个文件单独发送一条请求

2.向DNS服务器查询服务器IP地址

生成HTTP消息之后,接下来我们需要委托操作系统将消息发送给Web服务器

浏览器能够解析网址并生成HTTP消息,但它本身并不具备将消息发送到网络中的功能

在进行这一操作时,首先需要查询网址中服务器域名对应的IP地址

IP地址的简介:

IP地址简介

查询IP地址的方法,只要询问最近的DNS服务器就可以了,该操作称为域名解析

负责执行解析这一操作的就叫解析器,解析器的大致工作流程如下:

解析器工作流程

3.DNS服务器接力

DNS服务器的基本工作就是接收来自客户端的查询消息,然后根据消息的内容返回响应

来自客户端的查询消息包含以下3种:

(a)域名

服务器、邮件服务器(邮件地址中@后面的部分)的名称

(b)Class

在最早设计DNS方案时,NS在互联网以外的其他网络中的应用也被考虑到了,而Class就是用来识别网络的信息。不过,如今除了互联网并没有其他的网络了,因此Class的值永远是代表互联网的IN

(c)记录类型

表示域名对应何种类型的记录。例如,当类型为A时,表示域名对应的是IP地址;当类型为MX时,表示域名对应的是邮件服务器。对于不同的记录类型,服务器向客户端返回的信息也会不同

DNS基本工作

域名的层次结构:

DNS中的域名都是用句点来分隔,比如www.lab.glasscom.com

这里的句点代表了不同层次之间的界限,在域名中,越靠右的位置表示其层级越高

因此,com域的下一层是glasscom域,再下一层是lab域,在下面才是www这个名字

这种具有层次结构的域名信息会注册到 DNS 服务器中,而每个域都是作为一个整体来处理的。换句话说就是,一个域的信息是作为一个整体存放在DNS服务器中的,不能将一个域拆开来存放在多台DNS服务器中(现实情况不是一对一的)

负责管理lab.glasscom.com 这个域的 DNS 服务器的IP地址需要注册到glasscom.com域的DNS服务器中,而glasscom.com域的DNS服务器的IP地址又需要注册到com域的DNS服务器中

注意:在互联网中,com和jp的上面还有一级域,称为根域。根域不像com、jp那样有自己的名字,因此在一般书写域名时经常被省略,如果要明确表示根域,应该像www.lab.glasscom.com.

这样在域名的最后再加上一个句点,而这个最后的句点就代表根域

由于上级DNS服务器保管着所有下级DNS服务器的信息,所以我们可以从根域开始一路往下顺藤摸瓜找到任意一个域的DNS服务器

除此之外还需要完成另一项工作,那就是将根域的DNS服务器信息保存在互联网中所有的DNS服务器中,这样客户端只要能够找到任意一台DNS服务器,就可以通过它找到根域DNS 服务器

分配给根域DNS服务器的IP地址在全世界仅有13个,而且这些地址几乎不发生变化,因此将这 些地址保存在所有的DNS服务器中也并不是一件难事。实际上,根域DNS服务器的相关信息已经包含在DNS服务器程序的配置文件中了,因此只要安装了DNS服务器程序,这些信息也就被自动配置好了

下图是展示了DNS服务器之间是如何进行查询操作的

DNS查询操作

真实的互联网中还会通过缓存来加速DNS服务器的响应

4.委托协议栈发送消息

知道了IP地址之后,就可以委托操作系统内部的协议栈向这个目标IP地址发送消息了

大致结构如下图: