第一次握手:客户端向服务端发送SYN包。报文中标志位SYN=1,序列号seq=x(x为随机整数)。此时客户端进入了?SYN_SEND 同步已发送状态。
第二次握手:服务端回复客户端SYN+ACK包。报文中标志位SYN=1,标志位ACK=1,序列号seq=y(y为随机整数),确认号ack=x+1(x为客户端发送过来的序列号seq)。此时服务端进去SYN_RECV状态。
第三次握手:客户端回复服务端ACK包。确认报文的标志位ACK=1,确认号ack=y+1(y为第二次握手时服务端生成的序列号seq),序列号seq=x+1(x为第一手握手时客户端生成的序列号seq)。此时客户端和服务器进入ESTABLISHED状态,客户端与服务端成功建立了TCP连接。
第一次挥手:客户端数据传输完成后或准备终止发送数据时,会向服务端发送FIN包。报文中标志位FIN=1,序列号seq=u。此时客户端进入FIN_WAIT_1状态。
第二次挥手:服务端回复客户端ACK包。确认报文中标志位ACK=1,确认号ack=u+1,序列号seq=v。此时服务端进入close_wait关闭等待状态,客户端接受到ack应答包后,进入FIN_WAIT_2状态。
第三次挥手:等服务端数据发送完毕后会向客户端发送FIN包。报文中标志位FIN=1,标志位ACK=1,确认号ack=u+1,序列号seq=w。此时服务端进入LAST_ACK状态。
第四次挥手:客户端回复服务端ACK包。确认报文中的标志位ACK=1,确认号ack=w+1,序列号seq=u+1。此时客户端进入TIME_WAIT阶段。服务端收到确认报文后会立马释放TCP连接,而客户端发出报文后经过最长报文段寿命的2倍时长后释放TCP连接。
如果对标志位、序列号、确认号等不理解的,可以参考下面这篇博文,图片是引用此博文的。