为了表达TCP在建立连接、释放连接和数据传输期间所发生的所有状态及各状态可能发生的转换,可以通过有限状态机来描述。该状态机的11种状态如表8-2所示。
TCP 的状态 | |
状态 | 描述 |
CLOSED | 不存在连接 |
LISTEN | 服务器等待来自客户的连接请求 |
SYN_SEND | 已发送连接请求,等待ACK |
SYN_RCVD | 收到连接请求 |
ESTABLISHED | 连接建立,可传送数据 |
FIN_WAIT1 | 应用程序请求关闭连接,已发送FIN |
FIN_WAIT2 | 另一方已同意释放连接 |
TIMED_WAIT | 等待所有重传的报文段消失 |
CLOSING | 双方同时开始关闭连接 |
CLOSE_WAIT | 服务器等待应用进程释放连接 |
LAST_ACK | 服务器等待最后的确认 |
在任何时刻,TCP只处于某一种状态,并一直保持这个状态,直到某个事件发生。发生的事件使TCP进入一个新的状态,即事件可使TCP完成某种操作。状态转换表示一个状态到另一个状态的迁移,包括迁移的条件和迁移的动作。如图8-9所示为客户端和服务器端的状态转换图。
图中每一个框是TCP可能具有的状态,框中为TCP标准使用的状态名。状态之间的箭头表示状态之间可能发生的转换。转换的条件和转换的动作用“条件/动作”表示在箭头旁边。粗线箭头画出了一种典型的情形:一个客户端主动地连接到一个服务器上。其中粗实线箭头表示这个正常的客户端状态转换,粗虚线箭头表示正常的服务器状态转换,细线箭头则表示非正常(即非典型)的事件序列。
每个连接都开始于CLOSED状态。随着连接的进展,按箭头方向从一个状态转换到另一个状态。图中ⓘ标示客户端状态转化流程的标号;☐标示服务器端状态转化流程的标号,i=1~7。
客户端可能处于下列的6种状态之一:CLOSED、SYN_SENT、ESTABLISHED、FIN_WAIT1、FIN_WAIT2和TIME_WAIT。
1)标①处:客户端 TCP 状态开始于 CLOSED。
2)标②处:当客户端TCP处于CLOSED状态时,它能接收来自于客户应用进程的主动打开请求。当客户端TCP发起连接请求时,发送一个SYN值为1的报文段给服务器端TCP,并且进入状态 SYN_SENT。
3)标③处:客户端TCP处于SYN_SENT状态时,它能接收来自于对方TCP的SYN+ACK报文段。客户端TCP发送一个ACK报文段给对方TCP,并且进入状态ESTABLISHED,这时就进人数据传送阶段。只要客户端在发送和接收数据,它就会一直保持在这个状态。
4)标④处:客户端TCP处于ESTABLISHED状态时,它能接收来自于客户应用进程的关闭请求。当客户端TCP发送FIN值为1的报文段给对方TCP后,等待确认ACK的到达,进人状态FIN_WAIT1。
5)标⑤处:客户端TCP处于FIN_WAIT1状态时,它等待接收来自于服务器端TCP的ACK报文段。当它接收到服务器端TCP发出的ACK报文段时,则表示一个方向的连接已经关闭,进入状态FIN_WAIT2,客户端不发送任何信息。
6)标⑥处:客户端保持在FIN_WAIT2状态,等待服务器端从另一端关闭该连接。当它接收到来自服务器端TCP的FIN报文段后,就发送一个 ACK 报文段。这时,另一条连接也关闭了,并且进入状态TIME_WAIT。
7)标⑦处:当客户端处于TIME_WAIT状态时,它就启动定时器并且等待直到定时结束,定时器的值设定为最大报文段估计生存时间的两倍。在连接完全关闭之前,客户端一直处于TIME_WAIT状态,以确保该连接的所有的报文段都已经消失。当超时之后,客户端回到起始状态 CLOSED。
服务器端可以处于11种状态中的任一种状态,但在正常运行过程中,它可能处于下列6种状态之一:CLOSED、LISTEN、SYN_RCVD、ESTABLISHED、CLOSE_WAIT和LAST_ACK。
1)标☐1处:服务器端 TCP 状态开始于 CLOSED。
2)标☐2处:当服务器端TCP处于 CLOSED 状态时,它能接收来自于服务器应用进程的被动打开请求。然后进入状态 LISTEN。
3)标☐3处:当服务器端 TCP 处于 LISTEN 状态时,它能接收来自于客户端 TCP 的 SYN 报文段。当收到SYN值为1的连接请求报文后,服务器端TCP给客户端TCP发送 SYN+ACK 报文段,然后进入状态 SYN_RCVD。
4)标☐4处:当服务器端TCP处于 SYN_RCVD 状态时,它能接收来自于客户端 TCP 的 ACK 报文段。然后它就进人状态 ESTABLSHED,进人数据传送阶段。只要服务器端在发送和接收数据,它就会一直保持在这个状态。
5)标☐5处:当服务器端TCP处于 ESTABLISHED 状态时,它能接收来自于客户端的FIN报文段。当客户端的数据已经传送完毕,希望关闭这个连接,就发送FIN值为1的报文段给服务器。服务器给客户发送ACK报文段,然后进入状态CLOSE_WAIT。
6)标☐6处:当服务器端TCP处于CLOSE_WAIT状态时,它将一直等待,直到接收到来自服务器程序的关闭连接请求。然后,它就给客户端发送FIN报文段,并进入状态LAST_ACK。
7)标☐7处:当服务器端TCP处于 LAST_ACK 状态时,它等待最后的ACK报文段。当收到客户端TCP的 ACK 报文段后,服务器端就释放连接,然后回到初始状态CLOSED。