本文已参与「新人创作礼」活动,一起开启掘金创作之路。
输入URL后回车会发生什么?
总体来说会有以下几个过程:
-
浏览器输入url。解析url地址是否合法;
首先会对 URL 进行解析,分析所需要使用的传输协议和请求的资源的路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检查 URL 中是否出现了非法字符,如果存在非法字符,则对非法字符进行转义后再进行下一过程。 -
浏览器检查是否有缓存,有,直接显示,没有,需要请求资源;
浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。 -
DNS域名解析;
获取的是输入的 URL 中的域名的 IP 地址,首先会判断本地
是否有该域名的 IP 地址的缓存,如果有则使用,如果没有则向本地 DNS 服务器
发起请求。本地 DNS 服务器也会先检查是否存在缓存,如果没有就会先向根域名服务器
发起请求,获得顶级域名服务器的地址后,再向顶级域名服务器
请求,然后获得权威域名服务器的地址后,再向权威域名服务器
发起请求,最终获得域名的 IP 地址后,本地 DNS 服务器再将这个 IP 地址返回给请求的用户。 -
TCP连接,三次握手;
TCP 建立连接的三次握手的过程,首先客户端向服务器发送一个SYN 连接
请求报文段和一个随机序号
,服务端接收到请求后向服务器端发送一个SYN ACK
报文段,确认连接请求,并且也向客户端发送一个随机序号
。客户端接收服务器的确认应答后,进入连接建立的状态,同时向服务器也发送一个ACK 确认
报文段,服务器端接收到确认后,也进入连接建立状态,此时双方的连接就建立起来了。 -
发送HTTP请求,请求数据包;
如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个四次握手的过程。首先由客户端向服务器端发送使用的协议的版本号、一个随机数和可以使用的加密方法。服务器端收到后,确认加密的方法,也向客户端发送一个随机数和自己的数字证书。客户端收到后,首先检查数字证书是否有效,如果有效,则再生成一个随机数,并使用证书中的公钥对随机数加密,然后发送给服务器端,服务器端接收后,使用自己的私钥对数据解密,。这个时候双方都有了三个随机数,按照之前所约定的加密方法,使用这三个随机数生成一把秘钥,以后双方通信前,就使用这个秘钥对数据进行加密后再传输
。 -
服务器处理请求并返回HTTP报文;
当页面请求发送到服务器端后,服务器端会返回一个 html 文件作为响应,浏览器接收到响应后,开始对 html 文件进行解析,开始页面的渲染过程。 -
浏览器解析渲染页面;
浏览器首先会根据 html 文件构建 DOM 树
,根据解析到的 css 文件构建 CSSOM 树
,如果遇到 script 标签,则判端 是否含有 defer 或者 async 属性
,要不然 script 的加载和执行会造成页面的渲染的阻塞。当 DOM 树和 CSSOM 树建立好后,根据它们来构建渲染树
。渲染树构建好后,会根据渲染树来进行布局。布局完成后,最后使用浏览器的 UI 接口对页面进行绘制。这个时候整个页面就显示出来了。 -
连接结束,TCP四次挥手。
为什么三次握手?
为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。
已失效的连接请求报文段的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
三次握手能携带数据吗?
第一次、第二次握手不可以携带数据,而第三次握手是可以携带数据的
假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据,因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。也就是说,第一次握手可以放数据的话,其中一个简单的原因就是会让服务器更加容易受到攻击了。
而对于第三次的话,此时客户端已经处于 established
状态,也就是说,对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据。
丢包
丢包(Packet loss)是指一个或多个数据数据包(packet)的数据无法透过网上到达目的地。
半连接队列 : 服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列
。当然还有一个全连接队列
,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。