TCP建立/關閉連線時握手過程中的狀態情況
一句話總結:深入理解握手中的狀態情況
建立連線的3次握手和關閉連線的4次握手:
狀態轉換:
注:下面狀態轉換說明以客戶端主動關閉為例。
close:表示初始狀態
listen:伺服器端某個socket處於監聽狀態,可以接受客戶端連線
SYN_SENT:客戶端執行connect()連線伺服器時,傳送SYN(J)報文發起第一次握手,隨後進入SYN_SENT狀態。
SYN_RCVD:伺服器端接收到客戶端發來的SYN(J)報文完成,進入SYN_RCVD狀態完成第一次握手,並向客戶端傳送SYN(K)和ACK(J+1)報文,發起第二次握手。
ESTABLISHED:客戶端收到伺服器端發來的送SYN(K)和ACK(J+1)報文,狀態從SYN_SENT進入ESTABLISHED,完成
上面就完成了建立連線的3次握手,可以相互發送資料通訊了。
FIN_WAIT_1:客戶端主動關閉連線,向伺服器端傳送FIN(M)報文發起第一次握手,隨即進入FIN_WAIT_1狀態。
CLOSE_WAIT:伺服器端收到FIN(M)報文,完成第一次握手。然後並向客戶端傳送ACK(M+1)報文發起第二次握手,隨即進入CLOSE_WAIT狀態,被動關閉。
FIN_WAIT_2:客戶端收到ACK(M+1)報文後進入FIN_WAIT_2狀態。完成第二次握手
LAST_ACK:在CLOSE_WAIT狀態下如果沒有資料需要傳送,此時關閉socket,傳送FIN(N)給客戶端,發起第三次握手。如果客戶端沒有關閉,則不會發起第三次握手,此時客戶端停留在CLOSE_WAIT狀態,伺服器端停留在FIN_WAIT_2狀態。
TIME_WAIT:客戶端收到FIN(N)報文完成第三次握手,並向伺服器端傳送ACK(N+1)報文發起第四次握手,隨即進入TIME_WAIT狀態。客戶端等待2MSL超時後進入CLOSE狀態。
CLOSE:客戶端發起第四次握手後,等待2MSL超時後進入CLOSE狀態。伺服器端收到ACK(N+1)報文完成
上面即完成了關閉連線的4次握手。
上面關閉時是按照“客戶端發FIN—>客戶端收到伺服器端發的ACK—>客戶端收到伺服器端發的FIN—>客戶端發ACK”的時序來的,但是實際情況還有兩種可能,一是客戶端同時收到伺服器端發的ACK和FIN報文,二是客戶端先收到伺服器端發來的FIN報文之後才收到ACK報文。
特殊情況1:FIN_WAIT_1到TIME_WAIT的轉換。由於FIN_WAIT_2是接收到伺服器端的ACK報文後才能進入的狀態,而TIME_WAIT是收到伺服器端的FIN報文就可進入的狀態,如果客戶端發出FIN報文進入FIN_WAIT_1狀態後,同時收到FIN和ACK報文,可以直接進入TIME_WAIT狀態。
特殊情況2:當雙方都主動關閉socket時,同時傳送FIN報文,進入CLOSING狀態,表示雙方都在關閉socket。雙方接收到FIN報文後,傳送ACK報文,雙方接收到後依次進入TIME_WAIT狀態,等待2MSL超時後進入CLOSE狀態。