TCP是一个可靠的传输协议,在创建连接时会经历三次握手,在断开连接时会经历四次挥手。TCP 三次握手,其实就是 TCP 应用在发送数据前,通过 TCP 协议跟通信对方协商好连接信息,建立起TCP的连接关系。
    建立连接的三次握手
    所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。
    image.png
    TCP建立连接时要传输三个数据包,俗称三次握手(Three-way Handshaking)。可以形象的比喻为下面的对话:
    设备A:“你好,设备B,我这里有数据要传送给你,建立连接吧。”
    设备B:“好的,我这边已准备就绪。”
    设备A:“谢谢你受理我的请求。”

    • 第一次握手:客户端发送 SYN报文,并进入 SYN_SENT状态,等待服务器的确认;
    • 第二次握手:服务器收到 SYN报文,需要给客户端发送 ACK 确认报文,同时服务器也要向客户端发送一个 SYN 报文,所以也就是向客户端发送 SYN + ACK 报文,此时服务器进入 SYN_RCVD状态;
    • 第三次握手:客户端收到 SYN + ACK报文,向服务器发送确认包,客户端进入 ESTABLISHED 状态。待服务器收到客户端发送的 ACK 包也会进入 ESTABLISHED状态,完成三次握手。

    断开连接的四次挥手
    四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。当我们的应用程序不需要数据通信了,就会发起断开 TCP 连接。建立一个连接需要三次握手,而终止一个连接需要经过四次挥手。
    image.png
    断开连接需要四次握手,可以形象的比喻为下面的对话:
    设备A:“任务处理完毕,我希望断开连接。”
    设备B:“哦,是吗?请稍等,我准备一下。”
    等待片刻后……
    设备B:“我准备好了,可以断开连接了。”
    设备A:“好的,谢谢合作。”

    • 第一次挥手。客户端发起 FIN包(FIN = 1),客户端进入 FIN_WAIT_1 状态。TCP 规定,即使 FIN包不携带数据,也要消耗一个序号。
    • 第二次挥手。服务器端收到 FIN包,发出确认包 ACK(ack = u + 1),并带上自己的序号 seq=v,服务器端进入了 CLOSE_WAIT状态。这个时候客户端已经没有数据要发送了,不过服务器端有数据发送的话,客户端依然需要接收。客户端接收到服务器端发送的 ACK后,进入了FIN_WAIT_2状态。
    • 第三次挥手。服务器端数据发送完毕后,向客户端发送FIN包(seq=w ack=u+1),半连接状态下服务器可能又发送了一些数据,假设发送 seq 为 w。服务器此时进入了 LAST_ACK状态。
    • 第四次挥手。客户端收到服务器的 FIN包后,发出确认包(ACK=1,ack=w+1),此时客户端就进入了TIME_WAIT状态。注意此时 TCP 连接还没有释放,必须经过2*MSL后,才进入CLOSED状态。而服务器端收到客户端的确认包ACK后就进入了CLOSED状态,可以看出服务器端结束 TCP 连接的时间要比客户端早一些。