客户端建立连接和关闭连接的状态流程
CLOSED --> SYN_SEND --> ESTABLISHED --> FIN_WAIT_1 --> FIN_WAIT_2 --> TIME_WAIT --> CLOSED
服务端建立连接和关闭连接的状态流程
CLOSED --> LISTEN --> SYN_RECIEVED --> ESTABLISHED --> CLOSE_WAIT --> LAST_ACK --> CLOSED
详解
客户端发送SYN包后,进入SYN_SEND状态
服务端未收到SYN包之前,处于LISTEN状态
客户端发送SYN包后,处于SYN_SEND状态
服务端接收到SYN包并发送SYN+ACK包后,处于SYN_RECIEVED状态
客户端接收到SYN+ACK包后发送ACK包,处于ESTABLISHED状态
服务端接收到ACK包后,处于ESTABLISED状态
-------------------------------------------建立连接成功---------------------------------------------
客户端发出FIN包,在接收到服务端的ACK包之前,处于FIN_WAIT_1状态
服务端接收到客户端的FIN包,发送ACK包后,处于CLOSE_WAIT状态
客户端接收到服务端的ACK包后,接收到FIN包之前,处于FIN_WAIT_2状态
服务端发送FIN包后处于LAST_ACK状态
客户端接收到FIN包并发送ACK包之后处于TIME_WAIT状态
服务端收到ACK包后处于CLOSED状态
客户端处于TIME_WAIT状态等待2MSL后进入CLOSED状态
-----------------------------------------关闭连接成功--------------------------------------------------
TIME_WAIT状态
TIME_WAIT是为了实现全双工连接的可靠性关闭,用来重发可能丢失的ACK报文,需要持续2MSL的等待时间:如果在此时间内没有再次收到服务端的FIN包,说明ACK报文传输成功,否则要重新发送ACK包
其他状态
SYN_SEND --> CLOSED
因连接超时或主动关闭造成回到CLOSED状态
SYN_RECIEVD --> LISTEN
如果收到RST包,会返回到LISTEN状态
SYN_SEND --> SYN_RECIEVD
当客户端或服务端在SYN_SEND状态下收到SYN数据报文,则需要发送SYN+ACK数据报文,并进入SYN_RECIEVD状态,并准备进入ESTABLISHED状态
什么是RST报文?
就是TCP的异常中止。在通常情况下通过三次握手、四次挥手来建立连接和关闭连接,但是在有的情况下,TCP无法通过四次挥手来关闭连接,连接得不到释放,占用了资源。此时通过reset报文进行中止。
什么请求下使用RST报文?
- 客户端尝试与服务端未向外提供的端口进行连接时,服务端会直接返回reset报文
- 客户端或服务端在进行交互过程中出现异常(如系统崩溃),就会向对方发送reset报文,告知其释放此次连接
- 接收方接收到TCP报文,但发现该报文并不在已建立的TCP连接列表中,会向对方发送reset报文
- 在交互的双方长时间未收到对方发送的报文,并重传次数达到上限时,会向对方发送reset报文
- 有些应用开发者在设计系统时,当数据发送完后会利用reset报文快速释放连接,提高效率