> 文档中心 > TCP连接与断开,状态迁移图详解

TCP连接与断开,状态迁移图详解


一、概述

本文主要对TCP状态转移图中的三次握手和四次挥手进行总结,关于握手和挥手的流程大家可以看下面这篇:
https://blog.csdn.net/hjlogzw/article/details/122312496

二、详解状态迁移图

先来一张经典状态迁移图:
TCP连接与断开,状态迁移图详解
CLOSED:初始状态。

LISTEN:即服务端处于监听状态,可以接收客户连接了,一般在调用listen函数后处于该状态。

SYN_RCVD:一般表示服务端的状态,即接收到SYN报文后一直到客户端返回三次握手的最后一个ACK报文,在收到客户端ACK后就建立连接,进入到ESTABLISHED状态。

SYN_SENT:一般表示客户端的状态,与SYN_RCVD对应,当客户端调用connect函数时,首先会发送SYN报文,这时就进入到了SYN_SENT状态,并等待服务端的ACK报文。

ESTABLISHED:该状态代表连接已建立。

FIN_WAIT_1:当连接进入ESTABLISHED状态后,若一端想主动关闭连接,向对端发送FIN报文,此时就进入到FIN_WAIT_1状态,当对端回复ACK报文后,则进入到FIN_WAIT_2状态。

FIN_WAIT_2:处于改状态下的连接处于半连接状态,即表示一方要求关闭连接,但对方暂时还有数据要发送,稍后再关闭连接。

TIME_WAIT:当收到对方的FIN报文,并发送了ACK报文后,就变为TIME_WAIT状态,在等待2MSL后就回到初始状态CLOSED。值得注意的是,如果在FIN_WAIT_1状态下,收到对方同时带FIN标志和ACK标志的报文时,就可以直接进入到TIME_WAIT状态,不用经过FIN_WAIT_2状态,如下图所示。
TCP连接与断开,状态迁移图详解

CLOSING:这种状态比较罕见,一般情况下,在发送FIN报文后,应该先收到对方的ACK报文,再收到(或同时收到)对方的FIN报文。可是CLOSING状态表示的是发送FIN报文后,没有收到对方的ACK报文,而是也收到了对方的FIN报文,这其实说明双方是同时要close本次连接,如下图所示:
TCP连接与断开,状态迁移图详解

CLOSE_WAIT:即等待关闭,当对端调用close后发送FIN报文给本端,在回应ACK后就进入到了CLOSE_WAIT状态,接下来就需要考虑是否还有数据未发送给对方,没有的话就可以发送FIN报文给对方,从而关闭连接。

LAST_ACK:即被动关闭的一方在发送FIN报文后,等待对方的ACK报文时的状态,收到后就会进入到CLOSED初始状态。

注:
2MSL的原因:

  1. 让4次握手关闭流程更加可靠;4次握手的最后一个ACK是是由主动关闭方发送出去的,若这个ACK丢失,被动关闭方会再次发一个FIN过来。若主动关闭方能够保持一个2MSL的TIME_WAIT状态,则有更大的机会让丢失的ACK被再次发送出去。
  2. 防止最后一个响应包对新建连接造成影响。

参考:
https://blog.csdn.net/qq_32642107/article/details/107289298
https://www.csdn.net/tags/MtTaEg3sMzAxNTI3LWJsb2cO0O0O.html
https://baijiahao.baidu.com/s?id=1707040989071212058&wfr=spider&for=pc
https://wenku.baidu.com/view/d165f05c3b3567ec102d8a2a.html