一、三次握手介绍
- 第一次握手:建立连接。
客户端发送连接请求报文段,将SYN位置1,Seq 为x;然后客户端进入SYN_Send状态,等待服务器确认; - 第二次握手:服务器收到SYN报文段,并发送SYN+ACK报文段。
服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置ACK为 x+1 ;同时,自己还要发送SYN请求信息,将SYN位置为1,Seq为 y ;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_Recv状态; - 第三次握手:客户端收到服务器SYN+ACK报文段,并回应ACK报文段。
客户端收到服务器SYN+ACK报文段,然后将ACK位置位 y+1,向服务器端发送ACK报文段,这个报文段发送完毕后,客户端和服务器端都进入established状态,完成三次握手。
二、为什么建立连接需要三次握手?
-
首先非常明确的是两次握手是最基本的。
第一次握手,客户端发了个连接请求消息到服务端,服务端收到信息后知道自己与客户端是可以连接成功的,但此时客户端并不知道服务端是否已经接收到它的请求,所以服务端收到消息后的应答,客户端得到服务端的反馈后,才确定自己与服务端是可以连接上的,这是第二次握手。客户端只有确认了自己能与服务端连接上才能开始发数据,所以两次握手肯定是最基本的。 -
那为什么需要第三次握手呢?
第三次握手是为了防止已经失效的连接请求报文段突然又传到服务器,因而产生错误。
假设如果没有第三次握手,而是两次握手后就认为连接成功,那会发生什么呢?譬如说发起请求遇到这样的情况:客户端发出去的第一个连接请求由于某些原因在网络节点中滞留了导致延迟,直到连接释放的某个时间点才到达服务器,这是一个早已失效的报文,但此时服务端服务端仍然认为客户端的建立连接请求第一次握手,于是服务端回应了客户端,第二次握手。如果只有两次握手,那么到这里,连接就建立了。但是此时客户端并没有任何数据要发送,而服务端还在等待,造成很大的资源浪费。所以需要第三次握手,只有客户端再次回应一下,就可以避免这种情况。