TCP 的状态(一): TCP有限状态机 (FSM)
目录
最近一段时间在解决一个网络方面的 BUG,发现自己对 TCP 的状态了解得不够,于是复习了一遍 TCP 的各种状态与状态间的转换,并做了一个整理,以加深自己的理解。
网络上的两台设备想要一起工作,就必须使用相同的网络协议。像 TCP 这种复杂的协议,我们很难简洁地描述其各种确切的操作。所以我们试图使用有限状态机
来解释这个复杂的协议。
一. 有限状态机
有限状态机 (FSM : Finite State Machine)
又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。FSM 的四个基本概念如下:
状态 state
: 描述机器在特定时间上处于的 环境(circumstance)或状况(status)转换 Transition
: 从一种状态到另一种状态的行为(act)事件 Event
: 导致状态发生变化的事情动作 Action
: 机器从一种状态转换之前对事件所做的响应
FSM通过解释协议可以处于的所有不同状态、可以在每个状态中发生的事件、针对事件采取的操作以及结果发生的转换来描述协议。协议通常在第一次运行时以特定的开始状态启动。尔后,它遵循一系列步骤使其进入常规操作状态,并根据特定类型的输入或其他情况移动到其他状态。状态机之所以称为有限状态机,是因为只有有限数量的状态。
二. TCP 的操作与状态
对于 TCP 来说,可以使用 FSM 来描述一个连接的生命周期 : 一个 TCP 设备和另一个 TCP 设备之间的每个连接,都从一个空状态(null state) 开始,经过一系列的状态变化,直到建立了(established)连接。然后它将保持这种状态,直到遇到某种事件,它将进行一系列状态直到回到关闭状态。
我们使用三个缩写词来表示状态间转换的三种类型消息,它们对应于 TCP 头的标志。(关于 TCP 头的内容可以参见我之前的博客 《TCP 协议概述》) :
SYN
: 用于初始化和建立连接的同步消息FIN
: 一个 finish 消息,它表示设备想到终止连接ACK
: 一个确认消息,它表示设备已经接收到消息了
上图是一个简化的 TCP FSM, 描述了一个连接从关闭到连接,最后再到关闭的过程。真实环境中的情况要比这个复杂地多,但是每个连接都符合这个 FSM.
对该图的各种状态、事件、转换过程的解释如下:
CLOSED
- 状态 这是每个连接建立过程启动之前的默认状态。标准的叫法是
fictional
,这个状态表示设备之间没有连接 -- 要么是还没有创建,要么是刚刚销毁。 - Passive Open : 服务端通过在 TCP 端口上执行被动打开来启动连接建立的过程,同时,它设置了管理连接所需的数据结构(传输控制块或TCB),然后转换到
监听(LISTEN)
状态。 - Active Open, Send SYN: 客户端通过发送SYN消息开始连接设置,并为该连接设置TCB。然后转换到
SYN-SENT
状态
LISTEN
- 状态 服务端在等待接收从客户端发来的SYN消息。
- Receive Client SYN, Send SYN+ACK: 服务端接收到了来自客户端的 SYN 消息,发送服务端自己的SYN 并确认接收到的那个 SYN. 服务器转换到
SYN-RECEIVED
状态
SYN-SENT
- 状态 : 客户端已经发送了一条 SYN 消息,正在等待来自服务端的匹配的SYN
- Receive SYN, Send ACK: 如果发送了 SYN 的设备从另一设备接收到了 SYN, 但是没有接收到自己SYN的 ACK, 那么它奖确认收到的SYN, 然后转换到
SYN-RECEIVED
, 等待对方对其 SYN 的确认 - Receive SYN+ACK, Send ACK: 如果设备发送了 SYN, 同时接收到对对方对该 SYN 的确认,那么它将确认接收对方的SYN, 然后直接转换到连接 建立(ESTABLISHED) 状态
SYN-RECEIVED
- 状态: 设备已经从对方那里收到了一个SYN(连接请求),并发送了自己的SYN
- Receive ACK: 当设备接收到其发送的SYN的ACK时,它转换到已建立(ESTABLISHED) 的状态
ESTABLISHED
- 状态: 这是一个打开了的 TCP 的稳定状态(steady-state) . 一旦连接双方都进入了这种状态,就可以自由的交换数据了。这种状态将一直持续到某种将要关闭连接的事件发生。
- Close, Send FIN: 设备发送 FIN 消息,并转换到
FIN-WAIT-1
状态 - Receive FIN: 设备接收到对方发来的 FIN 消息请求关闭连接。其将确认此 FIN 此转换到
CLOSE-WAIT
状态
CLOSE-WAIT
- 状态: 设备已经收到了对方的 FIN 消息来请求关闭连接,它此时等待本地设备上的应用程序确认此请求并生成匹配的请求
- Close, Send FIN: 设备向发起 FIN 的设备发送 FIN。此后设备转换到
LAST-ACK
LAST-ACK
- 状态: 设备已经收到了 FIN,并确认了此FIN,且发送了自己的 FIN,它正在等待对自己的FIN 的ACK.
- Receive ACK for FIN: 设备接收 FIN 的 ACK.我们已经发送了 FIN 并得到了确认,我们收到了对方设备的 FIN 并确认了它,故我们将直接进入
CLOSE
状态。
FIN-WAIT-1
- 状态: 处于这种状态的设备正在等待其发送的 FIN 的 ACK, 或者正在等待来自对方设备的关闭连接请求
- Receive ACK for FIN: 设备接收到其关闭请求的确认,它将转为
FIN-WAIT-2
状态 - Receive FIN, Send ACK: 设备没有收到其 FIN 的 ACK, 但是收到了对方设备的 FIN, 本设备确认了这个 FIN, 并将转为
CLOSING
状态
FIN-WAIT-2
- 状态: 处于此状态的设备已经接收到了其 FIN 的 ACK, 现在正等待来自对方设备的 FIN.
- Receive FIN, Send ACK : 该设备接收到对方设备的 FIN, 确认该 FIN 后将转换到
TIME-WAIT
状态
CLOSING
- 状态: 设备接收到对方设备的 FIN 且给对方发送了 ACK, 但是本设备发送出去的 FIN 没有得到对方的确认。
- Receive ACK for FIN: 设备收到对方的 ACK, 之后将转到
TIME-WAIT
状态
TIME-WAIT
- 状态: 设备接收到对方设备的 FIN, 并返回了 ACK, 设备发送了 FIN 并得到了对方的 ACK 确认。此时除了确保 ACK 被对方接收之外,没有其它可做的了。
- Timer Expiration: 在指定的等待时间后,设备将转换为
CLOSED
状态