说明:
TCP 协议的操作可以使用一个具有 11 种状态的有限状态机( Finite State Machine )来表示,下图描述了 TCP 的有限状态机,图中的圆角矩形表示状态,箭头表示状态之间的转换,各状态的描述如附录1所示。图中用粗线表示客户端主动和被动的服务器端建立连接的正常过程:客户端的状态变迁用粗实线,服务器端的状态变迁用粗虚线。细线用于不常见的序列,如 复位、同时打开、同时关闭等。图中的每条状态变换线上均标有“事件/动作”:事件是指用户执行了系统调用( CONNECT 、 LISTEN 、 SEND 或 CLOSE )、收到一个报文段( SYN 、 FIN 、 ACK 或 RST )、或者是出现了超过两倍最大的分组生命期的情况;动作是指发送一个报文段( SYN 、 FIN 或 ACK )或什么也没有(用“-”表示)。
每个连接均开始于 CLOSED 状态。当一方执行了被动的连接原语( LISTEN )或主动的连接原语( CONNECT )时,它便会脱离 CLOSED 状态。如果此时另一方执行了相对应的连接原语,连接便建立了,并且状态变为 ESTABLISHED 。任何一方均可以首先请求释放连接,当连接被释放后,状态又回到了 CLOSED
正常状态转换:
我们用上图来显示在正常的 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 )。
附录:
附录1.tcp 11种状态说明
CLOSED 关闭状态,没有连接活动或正在进行 LISTEN 监听状态,服务器正在等待连接进入 SYN RCVD 收到一个连接请求,尚未确认 SYN SENT 已经发出连接请求,等待确认 ESTABLISHED 连接建立,正常数据传输状态 FIN WAIT 1 (主动关闭)已经发送关闭请求,等待确认 FIN WAIT 2 (主动关闭)收到对方关闭确认,等待对方关闭请求 TIMED WAIT 完成双向关闭,等待所有分组死掉 CLOSING 双方同时尝试关闭,等待对方确认 CLOSE WAIT (被动关闭)收到对方关闭请求,已经确认 LAST ACK (被动关闭)等待最后一个关闭确认,并等待所有分组死掉
参考:
http://wdqfirst.blog.163.com/blog/static/113347411201121511429120/