浏览器和网络总结(四)

223 阅读6分钟

前言

上一篇总结了cdndns,这篇总结一下tcp的三次握手和四次挥手以及url输入后发送了什么

url回车后发生了什么

url解析

浏览器首先会检测地址栏的内容是搜索内容还是合法的URL,一个合法的URL通常需要由协议、域名、端口、参数构成。

DNS解析

上一篇介绍过DNS解析的过程,充当了一个IP和域名之间的解析器,操作系统向本地域名服务器请求,通过cdn负载均衡等操作返回IP地址。

TCp连接

本机拿到ip地址后,向边缘节点请求。tcp是一种面向有连接的传输层协议,在建立连接前需要经过浏览器和服务端的三次握手。

发送http请求

经过三次握手之后,便正式和服务端建立了连接,浏览器发起http请求。一个http请求包含了请求行请求头请求主体

image.png

http响应

服务端在处理请求后,需要给浏览器响应。响应同样也包含了状态行响应头响应正文

image.png

解析资源

浏览器接收到资源后首先解析资源

  • 查看响应头的信息,根据指示做不同操作,比如重定向,加载缓存,开启gzip压缩
  • 查看响应头content-type,根据不同资源采用不同的解析方式

页面渲染

最后一步就渲染页面了,渲染页面的步骤如下:

  • 解析html,构建dom树
  • 如果遇到js脚本,会阻塞dom树的构建,先执行js
  • 解析css,构建css规则树
  • 合并dom树和css规则树,生成render树
  • 回流
  • 重排
  • 浏览器将各层信息发送给GPU,GPU将各层合成显示在屏幕上

在这里需要注意几点:

  • js会阻塞html的解析,因为html在gui渲染线程中,浏览器的策略是GUI渲染线程和js引擎互斥,所以一般将js放到页面最下方,避免阻塞html的解析。
  • 可以通过asyncdefer异步加载js,但是要注意这两者的区别,两者的下载过程都不会阻塞解析html。但是async下载完成后就会立即执行,同时执行顺序是看哪个文件先下载完成。defer则是等待html解析完成后才开始执行,执行顺序也和页面中的脚本顺序相同。
  • css不会阻塞dom树的构建,但是会阻塞html的渲染。css不会阻塞js的下载,但是会阻塞js的执行。所以一般将css文件放在页面的上方加载。

tcp的三次握手和四次挥手

三次握手

  1. 客户端给服务端发送一个SYN报文,并指明客户端的初始化序列ISN。这一步服务端可以确认客户端的发送和服务端的接收能力是正常的;
  2. 服务端接收到客户端的SYN报文后,会以自己的SYN报文作为应答,为了确认客户端的SYN报文,将客户端的ISN+1作为ACK的值。在这一步,客户端可以确认服务端的发送和客户端的接收能力正常,但是服务端无法确认客户端的接收能力是否正常;
  3. 客户端收到服务端的SYN报文后,发送一个ACK报文,值位服务端的ISN+1,服务端收到后双方就正式建立了连接。这一步,服务端可以确认客户端的接收和发送能力正常,自己的发送和接收能力也正常。

image.png

两次握手为什么不行

如果只有两次握手,发送端可以确认自己发送的消息对方能收到,对方发送的消息自己能收到。但是接收端只能确认对方发送的包自己能收到,无法确认自己发送的包对方能否收到。同时如果碰到网络阻塞问题会发送多个请求报文,延迟到达的请求又会与服务端建立连接,浪费了服务器的资源。

四次挥手

  1. 客户端发送一个FIN报文,报文指定一个序列号。此时客户端处于FIN_WAIT1状态,停止发送数据,等待服务端确认;
  2. 服务端收到FIN后会发送ACK报文,值为客户端的FIN序列号+1,表明服务端已经收到客户端断开连接的请求,此时服务端处于CLOSE_WAIT状态;
  3. 服务端也要断开连接,发送一个FIN报文并指定一个序列号。此时服务端处于LAST_ACK状态;
  4. 客户端收到FIN报文后,发送一个值为服务端序列号+1的ACK报文,表示收到了服务端断开连接的请求,此时客户端处于了TIME_WAIT状态。过一阵服务端收到了自己的ACK报文后进入CLOSE状态。服务端收到ACK报文后关闭了连接,也处于CLOSE状态。 image.png

为什么要有TIME_WAIT状态

主动断开连接的一方才有TIME_WAIT状态。需要TIME_WAIT状态的原因主要是:

  • 避免因为网络延迟的原因,上一个连接的报文被延迟了。服务端正好新建立了一个同样的四元组连接,延迟的报文可能会被客户端错误的接收,从而产生数据错乱。所以设计了TIME_WAIT状态,状态持续2MSL,保证两个方向上的数据包都被丢弃,原来连接的数据包在网络中自然消失;
  • 保证被关闭一方能正确的关闭。因为存在报文丢失的情况,如果立即关闭,服务端在没收到报文后会重新发送FIN报文,但是这时客户端已经关闭了会返回RST报文,服务端会解释成错误。所以设计了TIME_WAIT,服务端没有收到ACK后,就会触发TCP的重连机制,重新发送FIN报文,这个时间正好等于2MSL。客户端收到服务端重新发送的FIN报文后会把TIME_WAIT持续时间重置成2MSL;

四次挥手原因

服务端收到断开连接的FIN报文后并不会立即关闭连接,因为如果此时可能还有正在发送和没有发送完的报文,只有服务端将所有需要发送的报文全部发送完毕后,才会向客户端发送断开连接的报文。

参考链接

www.xiaolincoding.com/network/3_t…