面试官痛骂:”连输入url到页面的渲染发生了什么都不知道,要你何用“

输入URL到页面渲染发生了什么?

从浏览器地址输入url到页面展示的整个流程需要浏览器各个进程之间的配合,

  • 浏览器进程:主要负责用户交互、子进程管理和文件储存等功能
  • 渲染进程:从网络下载的HTML、Javascript、CSS、图片等资源解析为可以显示和交互的页面,默认情况下,每个tab标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • GPU进程:为了实现3DCSS的效果才设计出来的进程
  • 网络进程:面向渲染进程和浏览器进程等提供网络下载功能
  • 插件进程:主要负责插件的运行,因插件容易崩溃,所以需要通过它来隔离,保证插件进程崩溃不会对浏览器和页面造成影响。

输入url到页面渲染主要发生了:

  • URL解析
  • DNS域名解析
  • TCP连接
  • HTTP请求
  • 服务器处理报文并响应请求
  • 浏览器渲染
  • TCP断开连接

1 URL解析

🍑 URL:统一资源定位符(Uniform Resource Locator),每个有效的URL都指向一个唯一的资源。这个资源可以是一个HTML页面,一个CSS文档等。它由协议、主机、端口、文件路径、查询参数、锚点6部分组成。

  • Protocol通信协议,如http、https、ftp、file等。
  • Host主机,服务器的域名主机名或ip地址。
  • Port端口,默认是80。
  • Path文件路径,主机上的目录或文件地址。
  • Query查询参数,用为&分割的,可以给动态网页传递参数。
  • Fragment锚点网页位置指定标识符,用于指定网络资源中的某片断。也就是指定文章滚动到浏览器某个片段位置。是用来指导浏览器动作的,对服务器端完全无用。

🍑 URL中的特殊字符?、#、&

  • :分割url和查询。* &:分割查询参数,分号也可以分割。* #:位置标识符,#后面出现的任何字符,都会被浏览器解读为位置标识符。注意地,这些字符不会被发送到服务端。改变#后面的内容,浏览器只会滚动到响应位置,不会重新加载网页,但是会在浏览器的访问历史中增加一个记录,使用后退按钮就可以回到上一个位置。🍑 URL中的转义字符

由于URL无法显示一些特殊字符,比如我们传参中包含特殊字符的时候(act=go&status=5),本来想传的是act='go&status=5’的,但是浏览器会把&当作分割参数的特殊字符,此时就无法拿到我们想要的字符串了,此时转义字符(百分号+ASCII码值或16进制)就派上用场了。+(空格,%2B)、/(%2F)、?(%3F)、#(%23)、&(%26)、=(%3D)

🍑 URL中信息的读取

window.location对象常用属性作用
location.protocol返回所使用的web协议
location.hostname返回主机的域名
location.host返回主机的域名(包含端口)
location.href返回当前页面的url
location.search返回?后面部分(包含?)
location.hash返回锚点内容(#xxx)
window.location对象常用方法作用
location.assign()加载一个新的文档,跳转到指定的url
location.reload()重新加载当前文档
location.replace()用一个新url覆盖history对象中的当前记录,不会在history对象中生成一个新的记录

2 DNS域名解析流程

在进行URL的DNS域名解析之前,简单来说,一条域名的DNS记录会在本地有两种缓存:浏览器缓存和操作系统(OS)缓存。在浏览器中访问的时候,会优先访问浏览器缓存,如果未命中则访问OS缓存,最后再访问DNS服务器(一般是ISP提供),然后DNS服务器会递归式的查找域名记录,然后返回。

🍑 浏览器缓存:浏览器的缓存机制就是http缓存机制,是根据请求报文和响应报文的缓存标识来进行的。缓存过程分为两部分:强制缓存和协商缓存。

强制缓存:浏览器直接从本地缓存中获取数据,不与服务器进行交互。

协商缓存:浏览器发送请求到服务器,服务器判定是否可使用本地缓存

两种缓存方式都是使用本地缓存,前者无需与服务器交互,后者需要。

  • 强制缓存:在浏览器加载资源的时候,先检查缓存时间是否过期,若未过期则直接从缓存中查找请求结果,如果缓存时间过期或不存在该缓存结果,则向服务端发起请求。设置缓存时间方法有Expires(HTTP/1.0)Cache-Control(HTTP/1.1),后者max-age值高于前者优先级高。
  • 协商缓存:协商缓存不指定缓存的有效时间,而是在请求时直接发送资源标识到服务端确认缓存是否需要更新,如果请求响应返回的HTTP状态为304,则标识缓存仍然有效;否则返回状态码200、最新的资源和最新的资源标识。

🍑 什么是DNS?

DNS(Domain Name System,域名系统),因特网上作为域名和ip地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被及其直接读取的IP数串。通过主机名,最终得到该主机名对应IP地址的过程叫做域名解析,而域名到ip地址的解析过程的主要要点:当某一个应用进程需要把主机名解析为IP地址时,该应用进程就调用解析程序,并成为DNS的一个客户,把待解析的域名放在DNS请求报文中,以UDP用户数据报方式发给本地域名服务器(使用UDP是为了减少开销)。本地域名服务器在查找域名后,把对应的IP地址放在回答报文中返回。应用京城获得目的主机的IP地址后即可进行通信。若本地域名服务器不能回答该请求,则此域名服务器就暂时成为DNS中的另一个客户,并向其他域名服务器发起请求。

  • 域名层级关系特点:域名的结构由若干个分量组成,各分量之间“点”隔开,分别代表不同级别的域名;每一级的域名都由英文字母和数字组成,不超过63个字符,不区分大小写字母。完整的域名不超过255个字符。
  • 域名空间

  • 递归查询:如果主机所询问的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以DNS客户端,向其他根域名服务器继续发出查询请求报文,即替主机继续查询,而不是让主机自己进行下一步查询。(也就是,你等一下我,我替你找吧!)> 递归查询的工作原理:主机首先向其本地域名服务器进行递归 -> 本地域名服务器收到递归查询的委托后,也采用递归查询的方式向某个根域名服务器查询 -> 根域名服务器收到递归查询的委托后,也采用递归的查询方式向某个顶级域名服务器查询 -> 顶级域名服务器收到递归查询的委托后,也采用递归查询的方式向某个权限域名服务器查询。过程如图所示:


TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。客户端在收发数据前使用connect()函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种端点我们叫做套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字,例如,若IP地址为192.3.4.16而端口号为80,那么得到的套接字为192.3.4.16:80。

🍑 TCP报文首部常见字段信息

  • 序号(seq,Sequence Number):占4个字节,TCP连接中传送的字节流中每个字节都按顺序编号。例如,一段报文的序号字段值是301,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始。
  • 确认号(ack,Acknowledge Number):占4个字节,是期望收到对方下一个报文的第一个数据字节的序号,例如B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。
  • 标志位:每个标志位占用1位,共有6个,分别为URG(为1,紧急指针字段有效,告诉系统此报文有紧急数据)、ACK确认同步,为1,确认号字段有效,连接建立后所有报文的传输都必须把ACK置为1)、PSH(当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这是PSH=1)、RST(RST=1,TCP连接中出现严重差错,必须释放连接,然后再重新建立连接)、SYN(synchronize,请求同步,连接建立时用来同步序号,当SYN=1,ACK=0是连接请求报文,同意连接,则响应报文中应该使SYN=1,ACK=1)、FIN(终止标志,用来释放连接,FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放)。

🍑 TCP三次握手过程:

简易版:

详细版:

  • 第一次握手:客户端请求同步SYN=1(表示要建立连接,连接成功之后该位置再次置为0),请求序号seq=x(申请从哪一个字节开始发送,这个序号就表示当前已经发送到哪个序号),客户端进入同步发送状态,等待服务器的确认。
  • 第二次握手:通过传来的数据包中的SYN=1知道客户端请求建立连接,确认标志ACK置为1,ack=x+1(确认序号,代表x+1之前的字节服务器已经收到)。TCP是全双工协议,服务器也可能会给客户端发送数据,所以服务器也需要发送建立连接的同步标志SYN=1,seq=y表示服务器给客户端发送数据的开始序号y。
  • 第三次握手:因为连接是双向,服务器确认后只是客户端->服务器连通了,所以客户端也要确认一下,保证服务器->客户端已连接,此时就不需要请求同步标志SYN了。

4 发起HTTP请求

HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。一个请求报文由请求行、请求头部、空行和请求数据4部分组成。

🍑 什么是HTTP和HTTPS?

HTTP协议:超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议,所有的HTML文件都必须遵守这个标准,超文本就是HTML,传输表示由HTTP负责客户端和服务器的数据传输和解析。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。默认工作端口号为80

特点:

  • 支持客户/服务器模式;客户端和服务器通过网络交换信息。
  • 简单快速,客户向服务器请求服务时,只需传送请求方法和路径;
  • 灵活,HTTP允许传输任意类型的数据对象;
  • 无连接,无连接的含义是限制每次连接只处理一个请求;
  • 无状态,HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力,http是基于TCP的,当一个TCP连接关闭后,所有的HTTP请求/响应信息就会消失。
  • 跨平台,任何开发语言都可以实现HTTP或基于HTTP进行开发。

缺点就是协议不安全,原因是:

  • 数据没有加密:HTTP本身传递的是明文,不会加密这些信息,只要攻击者能够获取这些明文,用户的隐私就完全暴露了(窃听风险)。

  • 对称加密:通信双方使用同一把密钥进行加解密。对称加密具有加解密速度快,性能高的特点。

  • CA会把持有者的相关信息等打包,然后对这些信息进行Hash计算,得到Hash值。

  • CA将自己的私钥对Hash值加密,生成的Certificate Signature,也就是CA对证书做了签名。

  • 最后将证书签名添加在文件证书上,形成数字证书。

当客户端校验服务端的数字证书的过程,发生了什么:

  • 客户端使用同样的Hash算法获取该证书的Hash值H1
  • 然后,通过浏览器和操作系统中继承的CA公钥信息,浏览器收到CA证书后使用CA公钥解密Certificate Signature内容得到一个Hash值H2
  • 最后,比较H1和H2验证当前证书可不可信。

但事实上,证书的验证过程中还存在一个证书信任链的问题,因为我们向CA申请的证书一般不是根证书签发的,全世界的顶级 CA(Root CA) 就那么几个,每天都有很多人要向它申请证书,它也忙不过来啊,怎么办呢?它们授权给下一级证书去处理。比如window10系统下(运行命令打开mmc,在控制台点击文件添加管理单元,找到证书添加,就可以查看一些操作系统集成的证书了)

  • 客户端收到当前证书后,发现这个证书的签发者根本不是根证书,就无法根据本地已有的根证书中的公钥去验证当前证书是否可信,于是客户端根据当前证书的签发者是中间证书,然后CA请求申请该中间证书
  • 请求发现中间证书是由根证书签发的,因为根证书没有上一级了,也就是自签证书。应用软件会检查此证书是否预载于根证书清单上,如果有就用根证书中的公钥去验证中间证书,如果发现验证通过,就认为改中间证书可信。
  • 中间证书被信任后,可以使用中间证书的公钥去验证当前证书的可信性,如果验证通过,就可以信任当前证书。
  • 客户端向服务端发起建立HTTPS请求。
  • 服务器向客户端发送数字证书。
  • 客户端验证数字证书,证书验证通过后客户端生成会话秘钥
  • 服务器生成回话秘钥(双向验证此处服务端也会对客户端的证书验证)
  • 客户端与服务端开始进行加密会话。

🍑 请求方法

向请求URI指定的资源发送请求报文时,采用称为方法的命令。方法的作用在于,可以指定请求的资源按期望产生某种行为。方法中有GET、POST和HEAD等。

HTTP/1.1协议中共定义了八种方法,来表明请求url指定资源不同的操作方式。 HTTP1.0定义了三种请求方法:GET、POST、HEAD。 HTTP1.1新增了五种请求方法:OPTIONS、PUT、DELETE、TRACE、CONNECT方法。

🍑 请求头报文

用于HTTP协议交互的信息被称为HTTP报文。请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP报文本身是由多行(用CR+LF作换行符)数据构成的字符串文本。

  • 请求头部常见字段:

5 处理HTTP请求并返回HTTP报文

Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。

🍑 响应头报文

  • 常见响应包体:

🍑 常见响应状态码

6 浏览器渲染机制

渲染进程的核心工作是将HTML、CSS和Javascript转换为用户可以与之交互的网页。在这个工作过程中,输入的HTML金国一些子阶段,最后输出像素。按照渲染的时间顺序,子阶段大致分为:构建DOM树、计算样式、布局、分层、绘制、分块、栅格化和合成。 主要流程包括以下几步

  • 解析HTML生成DOM树
  • 解析CSS生成CSSOM规则树
  • 将DOM树与CSSOM规则树合并在一起生成渲染树
  • 根据渲染树进行页面元素的布局
  • 对渲染树进行分层操作,并生成分层树
  • 为每个图层生成绘制列表,并提交到合成线程
  • 合成线程将图层分成不同的图块,并通过栅格化将图块转化为位图
  • 合成线程给浏览器进程发送绘制图块指令
  • 浏览器进程会生成页面,并显示在屏幕上

🍑 构建DOM树

当渲染进程开始接收HTML数据时,主线程开始解析HTML并将其转换为浏览器能够理解的DOM树结构。当解析的过程中遇到script标签时,主线程暂停HTML的解析,从而进行js代码的加载、解析和执行,应为js代码中可能涉及对页面结构的修改,主线程必须等待js运行才能恢复对HTML文档的解析。因此我们可以通过在script标签上加上async或defer属性异步加载执行js代码,避免js阻塞HTML的解析。

HTML内容转换为浏览器DOM树结构的过程:字节 → 字符 → 令牌 → 节点 → 对象模型

  • 转换: 浏览器从磁盘或网络读取 HTML 的原始字节,并根据文件的指定编码(例如 UTF-8)将它们转换成各个字符。
  • 令牌化: 浏览器将字符串转换成 W3C HTML5 标准规定的各种令牌,例如,“”、“”,以及其他尖括号内的字符串。每个令牌都具有特殊含义和一组规则。
  • 词法分析: 发出的令牌转换成定义其属性和规则的“对象”。
  • DOM 构建: 最后,由于 HTML 标记定义不同标记之间的关系(一些标记包含在其他标记内),创建的对象链接在一个树数据结构内,此结构也会捕获原始标记中定义的父项-子项关系: HTML 对象是 body 对象的父项,body 是 paragraph 对象的父项,依此类推。

🍑 样式计算

目的是为了计算出DOM节点中每个元素的具体样式,在计算过程中需要遵守CSS的继承和层叠两个规则,这个阶段大体分为三步来完成。

  • CSS转换为浏览器能够理解的结构:当渲染引擎接收到CSS文本时,会执行一个转换操作,将CSS文本转换为浏览器可以理解的结构–StyleSheets,如以下例子:<<img src="http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><style> .box {width: 100px;height: 100px;background-color: green;margin-top: 20px;} </style></head><body><div class="box"></div></body></html> [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2lJKRFPA-1668003328449)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/376a1f9aad4f4072bc504e9fca698627~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?)]* 转换样式表中的属性值,使其标准化:rem这些属性,需要将所有值转换为渲染引擎容易理解的、标准化的计算值。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q5LlGWqL-1668003328449)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e25cc6defe54213b0135ef783552966~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?)]* 计算出DOM树中每个节点的具体样式。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZXkZkT8R-1668003328449)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b1d03f72b4aa4c5cbcab6da3aec734f2~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?)]🍑 布" style=“margin: auto” />

我们有DOM树和DOM树种元素的样式,还不足以显示页面,我们还不知道DOM元素的几何位置,所以计算出DOM树中可见元素的几何位置,我们把这个计算过程叫做布局

  • 创建布局树:浏览器会遍历DOM树中的所有可见节点,并把这些节点加到布局树中,而不可见的节点会被布局树忽略掉,如图中p这个元素被设置display:none,这个元素会被布局树忽略。
  • 布局计算:我们已经有了一颗完整的布局树,那么接下来就要根据DOM节点对应的CSS树中的样式,计算布局树节点的坐标位置。计算元素在视口上确切的位置和大小

🍑 分层

通常情况下,并不是布局树中的每一个节点都包含一个图层,如果一个节点没有对应的图层,那么这个节点就从属于父节点的图层。满足以下条件之一,元素就可以被单独提升为一个图层。

  • 拥有层叠上下文属性的元素会被提升为单独的一层
  • 需要剪裁的地方也会被创建为图层,剪裁就是节点内容超过节点限制,如div为200*200像素,但是文字显示区域超过了这个范围。
  • 如果出现滚动条,滚动条也会被提升为单独的层。

🍑 绘制

在完成图层树的构建后,渲染引擎会对图层树中的每个图层进行绘制,那么接下来我们看看渲染引擎是如何实现图层的绘制?举个图纸绘制图像例子

  • 把背景涂成暗色
  • 图纸中间画一个红色的圆
  • 在圆上绘制一个三角形

渲染引擎实现图层的绘制与之类似,把图层绘制拆分为多个小的绘制指令,然后再把指令按照顺序组成一个待绘制列表。

🍑 栅格化

  • 栅格化:将图块转化为位图(所谓位图就是能够看到的图层区域,位图是栅格化执行的最小单位)

绘制列表指令用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的。当图层的绘制列表准备好之后,主线程会把该绘制列表提交给合成线程,那么合成线程是如何工作的?

通常一个页面可能很大,用户只能看到其中一部分(用户可以看到的这个区域叫视口)。一个图层很大,页面需要滚动到底部,才能全部显示,通过视口,用户只能看到页面很小的一部分,所以要一次性绘制完图层所有的内容,会产生很大的开销。

基于开销这个原因,合成线程会将图层划分为图块,图块大小一般为256 * 256或 512 * 512。合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作就是有栅格化来执行的。栅格化过程都会使用GPU来加速生成,使用GPU生成位图过程叫快速栅格化,或者GPU栅格化。

🍑 合成和展示

一旦所有图块被栅格化,合成线程就会生成一个绘制图块的命令DrawQuad,然后将该命令提交给浏览器进程。浏览器进程里有一个叫viz的组件,用来接收合成线程发过来的DrawQuad命令,然后根据DrawQuad命令,然后其页面内容绘制到内存中,最后显示在屏幕上。

7 断开连接(tcp四次挥手)

  • 第一次挥手:客户端发出连接释放报文,停止发送数据,终止标志FIN=1,seq=u,客户进入FIN-WAIT-1状态。TCP规定FIN报文段即使不携带数据,也要消耗一个序号。(该说我都说,没啥好说的了,我想挂机)
  • 第二次挥手:服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,seq=v,服务端就就将进入CLOSE-WAIT关闭等待状态。客户端向服务器的方向就释放了,处于半关闭状态。客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然接受。(等一下嘛,我还没说完)
  • 第三次挥手:服务器继续将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,seq=w,服务器进入最后确认状态,等待客户端的确认。(我说完了,可以挂机了)
  • 第四次挥手:客户端收到服务器连接释放报文后,必须发出确认,ACK=1,ack=w+1,seq=u+1,客户端进入时间等待状态(TCP还没有释放,需要经过2 * MSL的时间,当客户端撤销相应的TCB,进入关闭状态)。服务端结束连接比客户端要早。(好的,我挂机了喔

面试官会问什么?

🍑 使用域名访问Web服务器过程?

🍑 讲讲DNS解析过程?

🍑 DNS为什么用UDP?

  • 能够及时传递数据。
  • 无需连接建立:TCP开始数据传输之前需要经过三次握手,UDP不需要任何准备即可进行数据传输。
  • 无连接状态:TCP需要在端系统中维护连接状态,此连接状态包括接受和发送缓存、拥塞控制参数以及序号与确认号的参数。UDP不维护连接状态,也不跟踪这些参数。
  • 分组首部开销小:TCP报文段都有20字节的首部开销,而UDP仅有8字节的开销。

🍑 递归查询与迭代查询的区别?

  • 递归查询:主机只向本地DNS服务器发出请求,然后等待肯定或否定答案
  • 迭代查询:本地服务i向DNS服务器发出请求,而根DNS服务器只是给出下一级DNS服务器的地址,然后本地DNS服务器再向下一级DNS发送请求直至得到最终答案。

🍑 为什么需要三次握手,两次不行吗?

  • 主要是为了防止已经失效的连接请求报文突然又传送到了服务器,从而导致不必要的错误和资源的浪费。
  • 两次握手只能保证单向连接是畅通的。因为TCP是一个双向传输协议,只有经过第三次握手,才能确保双向都可以接受到对方的发送的数据。

🍑 三次握手过程中可以携带数据吗?

第三次握手的时候,是可以携带数据的,但是第一次、第二次握手不可以携带数据,防止服务器受到攻击,因为此时还没有建立连接攻击者不需要理服务器的接收、发送能力是否正常,而第三次握手是已经建立连接

🍑 为什么连接的时候是三次握手,关闭的时候是四次挥手?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

🍑 TCP的三次握手一定保证传输可靠吗?

三次握手也不能保证连接就可靠,那么追加第四次握手呢?一样的,因为每次握手都是对收到上次握手的确认,却不能保证本次握手就能顺利到达。换句话说,握手发出的那一刻,只能说明上一次消息传递是顺畅的,却不能保证现在网络是畅通的。

🍑 关闭连接后,为什么TCP的三次握手,客户端最后还要发送一次确认?

主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

🍑 为什么TCP的四次挥手,客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime)报文最大生存时间,2MSL即两倍的MSL,TCP允许不同的实现可以设置不同的MSL值。

  • 保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度,发送了FIN+ACK报文请求断开,客户端还没有回应,于是服务器重新发送一次。 客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
  • 客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,这样新的连接中不会出现旧连接的请求报文。

🍑 如果已经建立了连接,但是客户端突然发生故障怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接

🍑 为什么很多站点第二次打开会很快?

浏览器缓存机制…

🍑 什么是重排、重绘和直接合成?

  • 重排(回流)当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档的过程。什么情况会导致回流:页面首次渲染、浏览器的窗口大小发生变化、元素的内容发生变化、元素尺寸或者位置发生变化、激活CSS伪类、查询某些元素或者调用某些方法、元素的字体大小发生变化、添加或者删除可见的DOM元素。
  • 重绘当页面中某些元素的样式发生变化,但不会影响其在文档流中的位置时,浏览器就会对元素进行重新绘制。什么操作会导致重绘:color、background相关属性(background-color、background-image等)、outline相关属性、border-radius、visibility、box-shadow
  • 直接合成:为什么我们为了避免重排和重绘而去采用 css3 的 transform 等属性呢?因为此时整个主线程的流程会被全部跳过,执行后续的流程,而后续的流程交给了在执行线程、光栅线程和 GPU 进程上执行没有占据主线程的资源,因此效率是最高的。

🍑 如何理解HTTP协议是无状态的?

对于Cookie和Session我是这样理解的!

🍑 在交互过程中如果数据传完了,还不想断开连接怎么办?怎么维持?

🍑 HTTP 如何实现长连接?什么时候会超时?

🍑 HTTPS流程是怎样的?

🍑 HTTPS一定安全可靠吗?

HTTPS协议本身到目前位置还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是HTTPS不够安全。

🍑 数字签名和数字证书是什么?

🍑 什么是双向认证?

🍑 什么是证书信任链?

站在大佬的肩膀上,可以看得更远!

3769869 “https://juejin.cn/post/7123216346283769869”)

🍑 在交互过程中如果数据传完了,还不想断开连接怎么办?怎么维持?

🍑 HTTP 如何实现长连接?什么时候会超时?

🍑 HTTPS流程是怎样的?

🍑 HTTPS一定安全可靠吗?

HTTPS协议本身到目前位置还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是HTTPS不够安全。

🍑 数字签名和数字证书是什么?

🍑 什么是双向认证?

🍑 什么是证书信任链?

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值