作者
MageByte技术团队
责编
郑丽媛
头图
CSDN下载自视觉中国
详解输入网址点击回车,后台到底发生了什么。透析HTTP协议与TCP连接之间的千丝万缕的关系。掌握为何是三次握手四次挥手?time_wait存在的意义是什么?全面图解重点问题,再也不用担心面试被问到。
大致流程
URL解析。DNS查询。TCP连接。服务器处理请求。客户端接收HTTP报文响应。渲染页面重点来了:
如何理解TCP的三次握手与四次挥手?每次握手客户端与服务端是怎样的状态?为何挥手会出现2MSL,遇到大量Socket处在TIME_WAIT或者CLOSE_WAIT状态是什么问题?三次握手与四次挥手的过程是怎样的?HTTP的报文格式又是怎样的?
URL解析
地址解析:首先判断你输入的是一个合法的URL还是一个待搜索的关键词,并且根据你输入的内容进行自动完成、字符编码等操作。
HSTS由于安全隐患,会使用HSTS强制客户端使用HTTPS访问页面。详见:你所不知道的HSTS[1]。
其他操作浏览器还会进行一些额外的操作,比如安全检查、访问限制(之前国产浏览器限制.icu)。
检查缓存
URL解析
DNS查询
DNS查询浏览器缓存:先检查是否在缓存中,没有则调用系统库函数进行查询。操作系统缓存:操作系统也有自己的DNS缓存,但在这之前,会向检查域名是否存在本地的Hosts文件里,没有则向DNS服务器发送查询请求。路由器缓存。ISPDNS缓存:ISPDNS就是在客户端电脑上设置的首选DNS服务器,它们在大多数情况下都会有缓存。根域名服务器查询
在前面所有步骤没有缓存的情况下,本地DNS服务器会将请求转发到互联网上的根域,下面这个图很好的诠释了整个流程:
DNS递归查询需要注意的的是:
递归方式:一路查下去中间不返回,得到最终结果才返回信息(浏览器到本地DNS服务器的过程)迭代方式,就是本地DNS服务器到根域名服务器查询的方式。什么是DNS劫持前端dns-prefetch优化
TCP连接建立与断开
TCP/IP分为四层,在发送数据时,每层都要对数据进行封装:
TCP/IP连接应用层:发送HTTP请求
浏览器从地址栏得到服务器IP,接着构造一个HTTP报文,其中包括:
请求报头(RequestHeader):请求方法、目标地址、遵循的协议等请求主体,请求参数,比如body里面的参数传输层:TCP传输报文
传输层会发起一条到达服务器的TCP连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息。在建立连接前,会先进行TCP三次握手。
网络层:IP协议查询MAC地址
将数据段打包,并加入源及目标的IP地址,并且负责寻找传输路线。判断目标地址是否与当前地址处于同一网络中,是的话直接根据Mac地址发送,否则使用路由表查找下一个地址,以及使用ARP协议查询它的Mac地址。
链路层:以太网协议
根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:
标头:数据包的发送者、接受者、数据类型数据:数据包具体内容Mac地址
以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是Mac地址。每一个Mac地址都是独一无二的,具备了一对一的能力。
主要的请求过程:
浏览器从地址栏中获取服务器的IP和端口号;浏览器与服务器之间通过TCP三次握手建立连接;浏览器向服务器发送报文;服务器接收报文处理,同时将响应报文发给浏览器;浏览器解析报文,渲染输出到页面;三次握手
在传输层传输数据之前需要建立连接,也就是三次握手创建可靠连接。
三次握手首先建立链接前需要Server端先监听端口,因此Server端建立链接前的初始状态就是LISTEN状态,这时Client端准备建立链接,先发送一个SYN同步包,发送完同步包后,Client端的链接状态变成了SYN_SENT状态。Server端收到SYN后,同意建立链接,会向Client端回复一个ACK。
由于TCP是双工传输,Server端也会同时向Client端发送一个SYN,申请Server向Client方向建立链接。发送完ACK和SYN后,Server端的链接状态就变成了SYN_RCVD。
Client收到Server的ACK后,Client端的链接状态就变成了ESTABLISHED状态,同时,Client向Server端发送ACK,回复Server端的SYN请求。
Server端收到Client端的ACK后,Server端的链接状态也就变成了的ESTABLISHED状态,此时建连完成,双方随时可以进行数据传输。
在面试时需要明白三次握手是为了建立双向的链接,需要记住Client端和Server端的链接状态变化。另外回答建连的问题时,可以提到SYN洪水攻击发生的原因,就是Server端收到Client端的SYN请求后,发送了ACK和SYN,但是Client端不进行回复,导致Server端大量的链接处在SYN_RCVD状态,进而影响其他正常请求的建连。可以设置tcp_synack_retries=0加快半链接的回收速度,或者调大tcp_max_syn_backlog来应对少量的SYN洪水攻击。
四次挥手
我们只要