TCP状态转换看起来很复杂,实质很只有两个主要状态,
1. 从CLOSED 到 ESTABLISHED
2. 从ESTABLISHED到CLOSED
TCP应用一般涉及客户和服务器应用,根据客户和服务器端的不同,对TCP的状态进行细分:
对照Unix 网络编程卷1 第33页的图,下面分别是客户端和服务器端的TCP状态转换过程。
客户端
客户端的TCP状态转换
- 客户端调用connect(),TCP发送SYN给服务器,执行主动打开,状态从CLOSED到SYN_SENT
- 客户处于SYN_SENT状态时,可能出现三种情况:
- 如果发送SYN后没有收到服务器响应,出现超时,状态回到CLOSED
- 如果接收到服务器的ACK和SYN,客户就会发送ACK作为对服务器的SYN确认,这时状态转换到ESTABLISHED,表示连接已建立
- 如果客户发送SYN的同时接收到服务器发来的SYN,状态会变为SYN_RCVD(同时打开),这属于不正常的客户端TCP状态,在unp第33面的TCP状态转换图中,使用细实线来连接这种状态转换,表示不正常的状态转换。在图例中说明,正常的客户端TCP状态转换使用粗实线来连接,正常的服务器TCP状态转换使用粗虚线连接。
- 客户端经过上述第二步进入ESTABLISHED后,它发送完数据,然后客户端应用程序调用close(),它的下一个状态是关闭,即CLOSED,但是,有几种情况可以进入CLOSED状态
- 客户端应用程序调用close后,TCP发送FIN给服务器,TCP处于FIN_WAIT_1状态,这个状态wait_1表示等待服务器对FIN的确认ACK,如果接收到服务器对FIN的确认,客户端TCP状态转换为FIN_WAIT_2,wait_2表示客户还在等待服务器的FIN.如果接收到服务器的FIN,客户就发送ACK对服务器的FIN进行确认,然后状态进入TIME_WAIT
- 同时接收到FIN和ACK,然后发送ACK给服务器,进入TIME_WAIT状态
- 客户端应用程序调用close后,TCP发送FIN给服务器,如果发送的同时接收到服务器的FIN,状态转换为CLOSING,表示同时关闭
服务器
服务器应用程序启动后,一直等待客户端连接, 当等到以后, 执行被动打开。
- 服务器程序启动后,如果程序编写正确,自动从初始状态CLOSED转换为LISTEN
- 服务器收到客户端的SYN, 然后发送SYN和ACK给客户端,这时服务器处于SYN_RCVD
- 服务器收到客户端的ACK, 状态变为ESTABLISHED
- 服务器收到客户端的FIN, 然后发送ACK给客户端,状态变为CLOSE_WAIT
- 服务器应用程序调用close时,TCP发送FIN给客户,状态为LAST_ACK,表示等待最后一个ACK.
- 服务器收到客户的ACK, 状态变为初始状态 CLOSED.