先看TCP状态机图:
(谢希任 计算机网络第六版)
注:粗实线箭头表示对客户进程的正常变迁,粗虚线箭头表示表示对服务器进程的正常变迁,细实线箭头表示异常变迁
我们先来说说图中的各个状态:
CLOSE:起点,即初始状态;
LISTEN:被动打开,服务器端的状态变为LISTEN状态(监听);
SYN-RECVD(同步收到):服务器端收到SYN后,状态为SYN,发送SYN+ACK;
SYN-SENT(同步已发送):应用程序发送SYN后,状态为SYN-SENT;
ESTABLISHED(已建立连接):SYN-RECVD收到ACK后,状态为ESTABLISHED,SYN-SENT收到SYN+ACK,发送ACK,状态为ESTABLISHED;
CLOSE_WAIT(关闭等待):服务器端在收到FIN后,发送ACK,状态变为CLOSE_WAIT,如果此时服务器端还有数据要传送,那么就发送,直到数据发送完毕,此时,服务器端发送FIN,状态变为LAST-ACK;
FIN-WAIT-1:应用程序端发送FIN,准备断开TCP连接,状态从ESTABLISHED状态变为FIN-WAIT-1;
FIN-WAIT-2:应用程序端只有收到服务器端ACK信号,并没有收到FIN信号,说明服务器端还有数据要传输,那么此时为半连接;
TIME_WAIT:有两种方式进入该状态:1.从FIN-WAIT-1进入,此时应用程序端口收到FIN+ACK,并向服务器端口发送ACK;
2.FIN-WAIT-2进入,此时应用程序端口收到了FIN,然后向服务器发送ACK;TIME-WAIT是为了实现TCP全双工连接的可靠性闭,用来重发可能丢失的ACK报文,需要持续2MSL,假如应用程序端口在进入TIME_WAIT后,2个MSL时间内并没有收到FIN,说明应用程序最后发出的ACK已经收到了;
下面我们重点来看一看关闭连接的状态转换:
我们假设通信双方是A,B,A是主动发起关闭方
(1)A首先主动发起FIN报文,准备关闭TCP连接,然后进入FIN-WAIT-1状态,然后如果A收到了ACK报文,就进入FIN-WAIT-2状态,而如果A收到ACK+FIN,则进入TIME_WAIT状态;进入FIN-WAIT-2状态,说明B还有数据发送给A,然后A发送ACK,并进入TIME-WAIT状态,当2个MSL内,没有收到FIN信号,那么TIME_WAIT状态就自动转换为CLOSED状态。(为什么呢?我们假设网络是不可靠的,最后A发送的ACK信号丢失,那么B就没有收到ACK,那么此时B还需要发送一个FIN给A,这个过程最多需要2MSL,所以如果过了2MSL,没有再次收到B的FIN,那么说明A发送的ACK被B收到了,所以可靠性的关闭连接)
(2)被动接受方:B在收到A的FIN报文后,知道A准备关闭TCP连接了(注意只是A单方面关闭,也就是说A还可以收数据,但是不准备发数据了),B将发送ACK给A,然后B进入CLOSE_WAIT状态,如果此时B也有数据发送给A,那么就一直发送好了,反正A不会发送数据了,此时A处于FIN-WAIT-2状态,当B的数据发送完毕后,那么B发送FIN给A,B进入LAST-ACK状态,当收到A发来的ACK信号后,A进入CLOSED状态。
原文:http://10706198.blog.51cto.com/10696198/1775571