详解TCP协议的连接管理机制——三次握手和四次挥手
一. 建立连接—三次握手
首先客户端和服务端都是关闭状态,也就是CLOSED状态。服务器端进入一个监听的LISTEN状态,阻塞等待客户端的连接。
- 第一次握手:客户端向服务端发送一个SYN的标志位以请求连接。此时客户端进入SYN_SEND状态,也就是开始阻塞等待服务器的应答。
- 第二次握手:服务器收到了客户端的SYN连接请求,也就处于SYN_RCVD状态。由于现在客户端向服务端单方面请求连接了,但是服务端还没有发送连接请求给客户端,要想双方都建立连接的话,就需要服务端也向客户端发送一个SYN请求。同时,我们还需要响应给客户端一个ACK应答,告诉客户端我们接收到了你的连接请求。
- 第三次握手:客户端接收到服务端的ACK应答和SYN连接之后,说明连接已经成功的建立,所以客户端处于ESTABLISHED状态。但是此时只有客户端知道连接建立完成,还需要返回给服务端一个ACK应答,告诉服务器我收到了你的连接请求。当服务端接收到最后一个ACK应答之后,就说明双方已经建成了连接通信,服务端也处于一个EXTABLISHED状态。
流程如图所示
二. 关闭连接—四次挥手
在数据传输之后,假设我们先由客户端来进行请求关闭连接。
- 第一次挥手:客户端调用close()方法关闭连接,向服务端发送一个FIN关闭连接请求,此时客户端就处于FIN_WAIT1状态。
- 第二次挥手:当服务端收到客户端的FIN之后,处于CLOSE_WAIT状态,说明服务器要准备关闭连接了。同时系统层面就会自动先返回一个ACK应答,告诉客户端我收到了你的关闭连接请求。此时收到ACK应答的客户端处于一个FIN_WAIT2状态,也就是继续等待的状态。
- 第三次挥手:服务端手动调用close()方法关闭连接,发送给客户端一个FIN结束报文段。此时服务端会进入LAST_ACK的状态,等待最后一个ACK的到来,以确定客户端收到了服务器发送的FIN。
- 第四次挥手:客户端收到服务器发来的结束报文段之后,进入TIME_WAIT状态,同时发送给服务端最后一个ACK响应,告诉服务器我收到了你的结束报文段,并等待报文的最大生存时间之后,确保对端收到最后一个ACK,再进入CLOSED状态,完成连接关闭。同时服务端收到最后一个ACK应答之后,由LAST_ACK状态转换为CLOSED状态,彻底关闭连接。