输入URL到跳转
流程总述:
- URL解析:解析 http 协议、端口、资源地址
- DNS解析:将域名解析为IP地址,并且通过ARP协议找到MAC地址
- TCP连接:TCP三次握手
- 发送HTTP请求
- 服务器处理HTTP请求并返回响应
- 浏览器解析并渲染页面
- 断开连接:TCP四次挥手
# 1. URL解析
https://www.baidu.com/
URL遵循的规则:
scheme://host.domain:port/path/filename
1
scheme
:定义应用层协议类型,如HTTP、HTTPS、FTPhost
:定义域主机(HTTP默认为www)domain
:定义域名port
:主机端口号(HTTP默认80,HTTPS默认443)path
:服务器上的资源路径filename
:资源名称
# 2. DNS解析
- 浏览器缓存:先查找本地浏览器的 DNS 缓存(浏览器的缓存)
- 操作系统缓存:查看本地 **hosts **文件有没有相应的映射记录
- 路由缓存:路由器DNS缓存
- ISP 的 DNS 服务器:向本地 DNS 服务器【网络运营商(电信、移动、联通)】发起查询请求。
- 本地DNS服务器收到请求后,会先查下自己的缓存记录,如果查到了直接返回就结束了;
- 如果没有查到,本地DNS服务器就会向DNS根域名服务器发起查询请求
- 根域名服务器收到请求后,发现是个
.com
的域名,递归向下请求.com
顶级域名服务器 - 本地 DNS 服务器接到回信后,向
.com
的顶级域名服务器发起查询请求,发现为163.com
,进入下一级查找 163.com
权威域名服务器接收到请求后,确认了是自己管理的域名,把 www.163.com 的ip告诉了 本地DNS服务器- 本地DNS服务器接收到回信后,将IP地址返回给本机,并做缓存
# 2. TCP三次握手建立连接
TCP/IP分模型建立连接
【应用层】:发送HTTP请求
【传输层】:传输TCP报文,建立TCP连接
【网络层】:IP协议 查询MAC地址(ARP寻址),进行数据传输、路由选择
【数据链路层】:以太网协议将数据分为以“帧”为单位的数据包进行发送
【物理层】:转化为0101的光电信号传输
三次握手:
【握手阶段】
- 建立链接前需要 Server 端先监听端口,因此 Server 端建立链接前的初始状态就是 LISTEN 状态,这时 Client 端准备建立链接。在第一次消息发送中,Client随机选取一个序列号作为自己的初始序号发送给Server,Client 端的链接状态变成了 SYN_SENT 状态;
- Server收到了来自Client的连接请求,如果在资源条件合理的情况下,服务器为该TCP连接分配缓存和变量。Server使用ACK对A的数据包进行确认,因为已经收到了序列号为
x
的数据包,准备接收序列号为x+1
的包,所以ack=x+1
,同时B告诉A自己的初始序列号,就是seq=y
;发送完 ACK 和 SYN 后,Server 端的链接状态就变成了 SYN_RCVD - Client 收到 Server 的 ACK 后,Client 端的链接状态就变成了 ESTABLISHED 状态。同时,Client 向 Server 端发送 ACK,回复 Server 端的 SYN 请求。Client恢复
seq=x+1
、ack=y+1
,Client为该TCP连接分配缓存和变量
# 3. 浏览器向web服务器发送HTTP请求
TCP三次握手之后,开始发送HTTP请求报文至服务器
HTTP请求报文格式:请求行
+ 请求头
+ 空行
+ 消息体
请求行包括请求方式(GET/POST/DELETE/PUT)、请求资源路径(URL)、HTTP版本号;
【默认GET请求,默认HTTP1.1,默认长连接Connection:keep-alive
】
# 4. 服务器处理请求并返回HTTP报文
服务器收到请求后会发出应答,即响应数据。
HTTP响应报文格式:状态行
+ 响应头
+ 空行
+ 消息体
状态行包括HTTP版本号、状态码、状态说明
# 5. 浏览器解析渲染页面
浏览器拿到响应文本后,解析HTML代码,请求js,css等资源,最后进行页面渲染,呈现给用户。
页面渲染一般分为以下几个步骤:
- 根据HTML文件解析出DOM Tree
- 根据CSS解析出 CSSOM Tree(CSS规则树)
- 将 DOM Tree 和 CSSOM Tree合并,构建Render tree(渲染树)
- reflow(重排):根据Render tree进行节点信息计算(Layout)
- repaint(重绘):根据计算好的信息绘制整个页面(Painting)
# 6. TCP四次挥手断开连接
【挥手阶段】
- Client请求关闭连接。首先主动向Server发送一个 TCP 首部
FIN=1
标志位为 的报文,Client随机选取一个序列号seq=u
作为自己的初始序号发送给Server,之后客户端进入FIN_WAIT_1
状态。 - Server回应
ACK
对Client的数据包进行确认,回复确认号ack=u+1
,同时Server告诉Client自己的初始序列号seq=v
;客户到服务器这个方向的连接就成了一一半关闭 CLOSED_WAIT 状态。由于Server可能还与他客户端同时在通信,或者可能此时对A的数据没有发送完,这次不会回复FIN
标志位。 - 第三条消息Server告诉Client可以断开连接,数据已传输完,。回复
FIN=1
,ACK=1
确认。Server依然恢复第二次的确认号ack=u+1
,因为这段时间A处于半关闭状态,并没有在发送数据 。并且回复seq =v
服务端进入 LAST_ACK状态 - Clint收到Server的反馈后,回送
ACK=1
,由于要断开连接不再发送数据了,seq=u+1
(序号为上次B回复A的ack),ack=w+1
。发送完后Clinet进入 TIME_WAIT状态。客户端在等待2MSL后,确保Server收到第四条消息后,自动进入 CLOSE状态。服务器收到第四条消息后进入了 CLOSE状态。至此客户端也完成连接的关闭。
编辑 (opens new window)
上次更新: 2021/06/27, 10:49:09