HTTP请求过程原理 前端面试题

在浏览器输入网址后,按回车键,要浏览的内容就会显示出来。那么在开发者眼中,这个过程是如何实现的呢?

其实,从输入 URL 到页面显示,大致可以分为三步:

  • 第一步:通过 DNS 进行域名解析,得到 IP 地址;

  • 第二步:找到 IP 地址对应的服务器,通过三次握手建立 TCP 连接,向服务器发送 HTTP Request 请求,并得到服务器的 Response 响应;

  • 第三步:浏览器根据响应结果渲染输出页面

第一步:DNS 解析过程

  • 在浏览器输入网址后,以 www.baidu.com 为例,系统会先检查本地hosts文件是否存在域名映射,若存在,则域名解析完成;

  • 若不存在,则会去查询本地DNS缓存,若存在,则域名解析完成;

  • 若不存在,则进一步查找本地DNS服务器,若存在,则解析完成;

  • 若不存在,本地 DNS 服务器会把请求发送至根DNS服务器,根DNS服务器收到请求后会返回一个负责该顶级域名服务器的IP。本地DNS服务器收到IP后,将会请求这个IP对应的服务器,逐层查找,直到找到网址baidu.com 主机及对应的 IP

第二步:TCP(传输控制协议)报文结构及三次握手

TCP.gif

TCP数据报文结构

  • Seq:序号,用来标识数据包;

  • Ack:确认序号,表示确认;

  • SYN:建立新连接的标识;

  • FIN:断开连接的标识。

三次握手

三次握手.jpg

  • 当客户端请求建立连接时,TCP 协议会设置 SYN 标志位和 Seq 序号。随后向服务器端发送数据包,然后进入 SYN-SEND 状态。

  • 服务器端收到该数据包后,检测到 SYN 标志位,同时设置 SYN 和 ACK 标志位,返回数据包给客户端,之后进入 SYN-RECV 状态。

  • 客户端收到确认包后,检测 ACK 标志位的值,如果正确,客户端进入 ESTABLISED 状态,连接建立成功。

  • 服务器端收到确认包后,检测 ACK 标志位,如果正确,服务器也进入 ESTABLISED 状态,至此双方连接建立成功。

  • 提示:为了确保数据的准确性,Seq 和 Ack 需要约定好:

第一次消息发送时 Seq 为系统生成:Ack 号 = Seq 号 + 传递的字节数 + 1;而之后发送的 Seq 号与接收到的 Ack 数值相同。

为什么需要三次握手?

  • 假如服务器端最后没有收到Ack确认包,就无法知道客户端是否建立连接成功,这样服务端将拒收任何来自客户端的消息。将不会发送数据给客户端。

超时重传

  • 假如在一定时间内发送方没有收到目标机器传回的确认包,那么就会启动超时重传机制,重传次数一般为3次,也可自定义。

第三步 TCP四次挥手断开连接及异常处理

三次握手建立连接后,双方就可以进行数据的发送和接收了。假如之后的客户端发起了断开连接的情况,那么正常情况下的过程如下图所示:

四次挥手.jpg

  • 客户端向服务器发送FIN数据包,告知服务器需要断开,之后进入FIN_WAIT_1状态

  • 服务端收到FIN数据包后,会向客户端发送Ack包,并继续处理未处理完的数据,然后进入CLOSE_WAIT状态

  • 客户端收到Ack包后进入FIN)WAIT_2状态

  • 服务端数据处理完毕后向客户端发送FIN包,告知可以准备断开连接了,然后进入LAST_ACK状态

  • 客户端收到来自服务端的FIN包后,发出Ack确认包,然后进入TIME_WAIT状态

  • 服务端收到客户端的Ack确认包后,关闭socket套接字,进入CLOSED状态。

为什么是四次挥手?

客户端发送FIN并不意味着TCP连接立即关闭,因为服务器端数据可能还没有发送完毕,为了保证可以继续发送数据,服务端的FIN包并不会立即发给客户端,所以就多出一次报文发送。


原文链接:HelloWeb前端网 » HTTP请求过程原理 前端面试题 » 感谢您的浏览,希望能有所帮助。

欢迎您加入“Helloweb” 学习交流群:HelloWeb-学习交流群 196291215 共同交流并结识同行,在这里说出您的收获与感想或有什么不同的观点,我们期待您的留言,分享,让我们一起进步!

喜欢 ()or分享