TCP有限状态机
TCP 有限状态机
很多人都知道TCP协议有名的三次握手
和四次挥手
,实际上它们是基于TCP协议的简约版抽象描述,而这两个动作
的背后本质上是TCP的协议转换;
TCP协议的操作流程可以使用一个包含11种状态的有限状态机( Finite State Machine )
来表示,下图描述了TCP有限状态机的运作流程,箭头指向表示状态之间的转换,粗实线表示客户端主动与和服务端建立连接的流程,粗虚线表示对应的服务端的状态转换的流程,细实线表示一些不常见的状态转换。
TCP有限状态机涉及到的11种状态及其描述如下表
TCP状态表
State | Description |
---|---|
CLOSED | 关闭状态,没有连接活动或正在进行 |
LISTEN | 监听状态,服务器正在等待连接进入 |
SYNC RCVD | 收到连接请求,尚未确认 |
SYNC SENT | 已发送连接请求,等待确认 |
ESTABLISHED | 连接建立,数据传输状态 |
FIN WAIT 1 | (主动关闭)发送关闭连接请求,等待确认 |
FIN WAIT 2 | (主动关闭)收到对方关闭确认,等待对方关闭请求 |
TIMED WAIT | 完成所有封闭,等待所有分组消失 |
CLOSING | 双方尝试关闭,等待对方确认 |
CLOSE WAIT | (被动关闭)收到对方关闭请求,已确认 |
LAST ACK | (被动关闭)等待最后一个关闭确认,并等待所有分组消失 |
TCP协议状态的转换
-
服务器端首先执行 LISTEN 原语进入被动打开状态(
LISTEN
),等待客户端连接; -
当客户端的一个应用程序发出 CONNECT 命令后,本地的 TCP 实体为其创建一个连接记录并标记为
SYN SENT
状态,然后给服务器发送一个 SYN 报文段; -
服务器收到一个 SYN 报文段,其 TCP 实体给客户端发送确认 ACK 报文段同时发送一个 SYN 信号,进入
SYN RCVD
状态; -
客户端收到 SYN + ACK 报文段,其 TCP 实体给服务器端发送出三次握手的最后一个 ACK 报文段,并转换为
ESTABLISHED
状态; -
服务器端收到确认的 ACK 报文段,完成了三次握手,于是也进入
ESTABLISHED
状态。在此状态下,双方可以自由传输数据。当一个应用程序完成数据传输任务后,它需要关闭 TCP 连接。假设仍由客户端发起主动关闭连接。 -
客户端执行 CLOSE 原语,本地的 TCP 实体发送一个 FIN 报文段并等待响应的确认(进入状态
FIN WAIT 1
); -
服务器收到一个 FIN 报文段,它确认客户端的请求发回一个 ACK 报文段,进入
CLOSE WAIT
状态; -
客户端收到确认 ACK 报文段,就转移到
FIN WAIT 2
状态,此时连接在一个方向上就断开了; -
服务器端应用得到通告后,也执行 CLOSE 原语关闭另一个方向的连接,其本地 TCP 实体向客户端发送一个 FIN 报文段,并进入
LAST ACK
状态,等待最后一个 ACK 确认报文段; -
客户端收到 FIN 报文段并确认,进入
TIMED WAIT
状态,此时双方连接均已经断开,但 TCP 要等待一个 2 倍报文段最大生存时间 MSL ( Maximum Segment Lifetime ),确保该连接的所有分组全部消失,以防止出现确认丢失的情况。当定时器超时后, TCP 删除该连接记录,返回到初始状态(CLOSED
)。 -
服务器收到最后一个确认 ACK 报文段,其 TCP 实体便释放该连接,并删除连接记录,返回到初始状态(
CLOSED
)。
同时主动建立连接
当出现同时打开的情况时,状态转换与正常的流程不同。两端几乎在同时发送SYN,并进入SYN_SENT
状态。当每一端收到SYN时,状态变为SYN_RCVD
,同时它们都再发SYN并对收到的SYN进行确认。当双方都收到SYN及相应的ACK时,状态都变迁为ESTABLISHED
。下图显示了这些状态转换的过程。
同时主动关闭TCP连接
C/S端双方同时执行主动关闭是可能存在的,而TCP协议也允许这样连接的两端同时发起关闭请求。如下图,C/S两端同时发起关闭请求,即同时向对方发送了FIN报文段,根据有限状态机的描述,此时双方都由ESTABLISHED
变为FIN_WAIT_1
状态,紧接着各自收到对方的FIN后,状态都由FIN_WAIT_1
变迁到CLOSING
,并发送最后的ACK报文段,最后都进入TIME_WAIT
状态。