总体流程:
- DNS域名解析
- 建立TCP连接:三次握手
- 客户进程发送HTTP请求报文
- 服务器处理请求并返回HTTP响应报文
- 浏览器解析渲染画面
- 释放TCP连接:四次挥手
一. DNS域名解析
1.浏览器获取了这个url,先从 浏览器缓存–系统缓存–路由器缓存 当中查看是否解析过,如果缓存中都没有
2.则浏览器进程向DNS服务器发送查询报文
该报文是UDP数据报的形式,其UDP首部的目的端口号为53
(然后封装成IP数据报,通过以太网发送到DNS本地服务器)
域名解析过程:
主机先向本地域名服务器(代理)进行递归查询,
本地域名服务器采用迭代查询,先向某个根域名服务器查询,根域名服务器告诉本地域名服务器 下一次应查询的顶级域名服务器的IP地址
本地域名服务器又向顶级域名服务器进行迭代查询,顶级域名服务器告诉本地域名服务器,下一次应查询的权限域名服务器的IP地址
本地域名服务器向权限域名服务器进行迭代查询,权限域名服务器告诉本地域名服务器所查询的域名的IP地址
3. DNS服务器发回响应报文
将响应报文封装成UDP数据报,再封装成IP数据报,通过以太网传给浏览器进程
二. 建立TCP连接(三次握手)
【客户进程收到正确的ip后】,会与Web服务器建立TCP连接
- 首先,TCP服务器进程先创建传输控制块TCB,用来存储TCP连接中的重要信息(TCP连接表,当前发送和接收序号),TCP服务器进入监听状态,等待TCP客户的连接请求----------被动打开连接;
- TCP客户进程创建传输控制块TCB,向TCP服务器进程发送TCP连接请求报文段,客户端进程进入同步已经发送状态,
SYN同步位=1 (连接请求or连接请求的确认),
seq=x 随机初始序号,(TCP规定SYN=1时的报文段不携带数据)!----------主动打开连接 - TCP服务器进程收到请求报文段后,如果同意连接就发送TCP请求的确认报文段,并进入同步已接收状态,
SYN=1(连接请求or连接请求的确认);
ACK=1(建立连接后ACK都为1);
ack=x+1表示期待TCP客户端进程下一次发送的下一个数据序号;
seq=y 随机初始序号 - TCP客户端进程收到TCP连接请求的确认报文段后,需要向服务器进程发送对确认报文段的确认(此时是普通的确认报文段,可以携带数据),并进入连接已建立状态,
ACK=1 (连接已建立);
seq=x+1 (客户进程发送的第一个报文段为x,所以下一个是x+1);
ack=y+1 ;
TCP服务端进程收到后也进入连接已建立状态
三. 发送HTTP请求
客户进程向Web服务器发送HTTP请求报文,其封装成TCP报文段,HTTP目的端口号 80
,HTTPS端口号 443
将TCP封装在IP数据报,通过以太网传给Web服务器
四. 服务器处理请求并返回HTTP报文
Web服务器收到IP数据报,解析HTTP请求报文交付给本服务器中的HTTP服务器端进程;
HTTP服务器端进程解析请求报文内容,按要求查找资源,调用数据库信息等,将结果封装到HTTP响应报文返回客户进程;
五. 浏览器解析渲染画面
客户进程收到响应报文;
浏览器解析渲染页面是一个从上到下的过程。
1.解析HTML标签,构建DOM树 。
2.解析CSS,构建CSSOM树。
3.把DOM和CSSOM组合成渲染树(render tree)。
4.在渲染树的基础上进行布局,计算每个节点的几何结构。
5.把每个节点绘制到屏幕上(painting)。
六. TCP连接的释放(四次挥手)
-
在连接已建立状态,假设TCP客户端进程主动关闭TCP连接,TCP客户进程会发送TCP连接释放报文段
FIN=1,终止位为1用来释放一个连接(TPC规定终止位=1的报文段即使不携带数据,也要消耗掉一个序号)
ACK=1,(建立连接后ACK都为1)
ack=v ,v是客户端进程收到的数据的最后一个字节序号+1,即期待服务器下一次发送的第一个字节序号
seq=a,a是客户进程之前传送的数据的最后一个字节的序号+1 -
TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入半关闭状态
ACK=1
ack=a+1 对释放报文段的确认
seq=v, v是服务器之前传过的数据的最后一个字节序号+1
此时,从TCP客户端进程到 服务器进程的方向释放了,TCP连接处于半关闭状态,但服务器仍可以向客户端发送 -
TCP服务器进程发送TCP连接释放报文段 进入最后确认状态
FIN=1,表示这是一个连接是释放报文
ACK=1
ack=a+1,对之前收到的连接释放报文段的重复确认,(半关闭状态期间 客户进程不能再给服务进程发消息)
seq=b,在半关闭状态下,服务进程可能又发送了一些数据 -
TCP客户进程收到TCP连接释放报文段后,发送该报文段的普通TCP确认报文段
ACK=1
ack=b+1
seq=a+1 客户端之前发送的TCP连接释放报文段虽然不携带数据,但要消耗一个序号
服务器进程关闭; 客户端进程经过两倍MSL(最长报文段寿命)后进入关闭‘