三次握手
TCP 三次握手,其实就是建立一个 TCP 连接,客户端与服务器交互需要 3 个数据包。握手的主要作用就是为了确认双方的接收和发送能力是否正常,初始序列号,交换窗口大小以及 MSS 等信息。
-
第一次握手:客户端发送
SYN
报文,并进入SYN_SENT
状态,等待服务器的确认; -
第二次握手:服务器收到
SYN
报文,需要给客户端发送ACK
确认报文,同时服务器也要向客户端发送一个SYN
报文,所以也就是向客户端发送SYN + ACK
报文,此时服务器进入SYN_RCVD
状态; -
第三次握手:客户端收到
SYN + ACK
报文,向服务器发送确认包,客户端进入ESTABLISHED
状态。待服务器收到客户端发送的ACK
包也会进入ESTABLISHED
状态,完成三次握手。
四次握手
数据传输结束后,通信的双方都可以释放连接。现在客户端和服务端都处于 ESTABLISHED
状态。
-
第一次挥手。客户端发起
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 连接的时间要比客户端早一些。
参考资料
1.