第一步 浏览器生成消息
生成HTTP请求消息
浏览器解析URL
HTTP协议的URL格式:
http://[用户名(可省略)]:[密码(可省略)]@[Web服务器域名]:[端口号(可省略)][文件路径名]
,例如:http://user:password@www.glasscom.com:80/dir/file1.htm
FTP协议的URL格式:
ftp://[用户名(可省略)]:[密码(可省略)]@[ftp服务器域名]:[端口号(可省略)][文件路径名]
,例如:ftp://user:password@ftp.glasscom.com:21/dir/file1.htm
计算机本地文件URL格式:
file://[计算机名(可省略)][文件路径名]
,例如:file://localhost/home/user/Desktop/wps-office-prometheus.desktop
发送电子邮件的URL格式:
mailto:[邮件地址]
,例如:mailto:tone@glasscom.com
浏览器根据开头就能确定是哪种协议,进而根据对应的协议格式对URL进行解析。
例1:解析如下URL
http://www.lab.glasscom.com/
:访问/目录下的index.html或default.html;http://www.lab.glasscom.com
:访问/目录下的index.html或default.html;http://www.lab.glasscom.com/what
:若/what是文件,则访问/目录下的what文件,若what是目录,则访问/what目录下的index.html或default.html;
生成HTTP请求消息
HTTP请求消息格式如下:
HTTP的主要方法及其含义如下图所示:
HTTP请求消息中主要的头字段有如下这些:
向DNS服务器查询Web服务器的IP地址
- 客户端将查询消息发送给最近的DNS服务器(地址填写在客户端的TCP/IP设置中);若该DNS服务器的缓存中存放了
www.lab.glasscom.com
Web服务器的IP地址,则直接返回相应IP地址; - 如果该DNS服务器中没有存放
www.lab.glasscom.com
Web服务器的IP地址,就需要从根域向下查找(每台DNS服务器都会保存根域DNS服务器的IP地址,共13个); - 该DNS服务器将查询消息发送给根域DNS服务器,根域DNS服务器根据域名结构判断出该域名属于com域,将com域DNS服务器的IP地址返回该DNS服务器,该DNS服务器再向com域DNS服务器发送查询消息;
- 一直类似以上步骤,直到查询消息到达目标DNS服务器——com.glasscom.lab域DNS服务器;com.glasscom.lab域中如果存在
www.lab.glasscom.com
这个域名,则目标DNS服务器就会将其IP地址发送给离客户端最近的DNS服务器;否则,目标DNS服务器将”不存在”这一结果发送给离客户端最近的DNS服务器; - 离客户端最近的DNS服务器将查询结果返回给客户端,同时将此次查询结果缓存,以便下次客户端查询时能够快速响应(DNS服务器缓存的信息都会有一个有效期,过了有效期缓存的信息会被删除);
委托协议栈发送消息
数据通过类似管道的结构来流动:
收发数据大体分为4个阶段:
- 创建套接字阶段;
- 连接阶段(将管道连接到服务端的套接字上);
- 通信阶段(收发数据);
- 断开阶段(断开管道并删除套接字);
如下示意图:
创建套接字阶段
创建套接字通过调用socket程序组件完成,套接字创建完成后,协议栈(socket程序组件)返回关于此套接字的描述符。
连接阶段
连接目的服务器通过调用connect程序组件完成,connect程序组件需接收3个参数:对应套接字的描述符、目的服务器的IP地址与目的端口号(用来指定要连接的服务器端的套接字)。最终,客户端的套接字与服务器端的套接字连接。
通信阶段
调用write程序组件将请求消息从客户端的套接字传送到服务器端的套接字。当服务器端接收到请求消息后,将请求消息解析并执行相应的操作,然后向客户端返回响应消息。接收响应消息通过调用read程序组件完成,read程序组件需接收1个参数——接收到的响应消息在内存中的地址,这一内存区域称为接收缓冲区。
断开阶段
Web服务器发送完响应消息后,会主动执行断开操作;断开操作传回客户端之后,客户端调用close程序组件断开连接、删除套接字。
在HTTP1.0版本中,HTML文档与图片视为独立的对象,每获取一次数据,就要执行一轮创建套接字、连接、通信与断开的操作;因此,如果一个网页中包含多张图片,就必须重复多轮上述操作,因此在HTTP1.1版本中设计了可以在一次连接中收发多个请求与响应的方法,当所有数据都请求完成后,客户端的应用程序会主动执行断开操作。