TCP的11種狀態
為了邏輯更加清晰,假設主動打開連接和關閉連接皆為客戶端,被動打開連接和關閉連接皆為服務端
-
客戶端獨有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT
-
服務器獨有的:(1)LISTEN (2)SYN_RCVD (3)CLOSE_WAIT (4)LAST_ACK 。
-
共有的:(1)CLOSED (2)ESTABLISHED 。
1. LISTEN(服務端)
首先服務端需要打開一個 socket 進行監聽,狀態為LISTEN。
有提供某種服務才會處于LISTENING狀態, TCP狀態變化就是某個端口的狀態變化,提供一個服務就打開一個端口,例如:提供www服務默認開的是80端口,提供ftp服務默認的端口為21,當提供的服務沒有被連接時就處于LISTENING狀態。FTP服務啟動后首先處于偵聽(LISTENING)狀態。處于偵聽LISTENING狀態時,該端口是開放的,等待連接,但還沒有被連接。就像你房子的門已經敞開的,但還沒有人進來。
在客戶端發送連接請求后,等待匹配的連接請求:
客戶端通過應用程序調用connect進行active open.于是客戶端tcp發送一個SYN以請求建立一個連接.之后狀態置為SYN_SENT. /*The socket is actively attempting to establish a connection. 在發送連接請求后等待匹配的連接請求 */
2. SYN_SENT(客戶端)
當請求連接時客戶端首先要發送同步信號給要訪問的機器,此時狀態為SYN_SENT,同時會開啟一個定時器,如果超時還沒有收到ACK會重發 SYN。正常情況下SYN_SENT狀態非常短暫。
例如要訪問網站http://www.baidu.com ,如果是正常連接的話,用TCPView觀察 IEXPLORE .EXE(IE)建立的連接會發現很快從SYN_SENT變為ESTABLISHED,表示連接成功。SYN_SENT狀態快的也許看不到。
3. SYN-RECEIVED(服務端)
收到和發送一個連接請求后,等待對方對連接請求的確認。當服務器收到客戶端發送的同步信號時,將標志位ACK和SYN置1發送給客戶端,此時服務器端處于SYN_RCVD狀態,如果連接成功了就變為ESTABLISHED,正常情況下SYN_RCVD狀態非常短暫。
4. ESTABLISHED(共有)
ESTABLISHED狀態是表示兩臺機器正在傳輸數據,觀察這個狀態最主要的就是看哪個程序正在處于ESTABLISHED狀態。
5. FIN_WAIT_1(客戶端)
主動關閉(active close)端應用程序調用close,于是其TCP發出FIN請求主動關閉連接,之后進入FIN_WAIT_1狀態.
6. FIN-WAIT_2(客戶端)
主動關閉端接到服務端的ACK后,就進入了FIN-WAIT-2。這就是著名的半關閉的狀態了,這是在關閉連接時,客戶端和服務器兩次握手之后的狀態。在這個狀態下,應用程序還有接受數據的能力,但是已經無法發送數據,但是也有一種可能是,客戶端一直處于FIN_WAIT_2狀態,而服務器則一直處于WAIT_CLOSE狀態,而直到應用層來決定關閉這個狀態
7. CLOSE_WAIT(服務端)
服務端端TCP接到FIN后,就發出ACK以回應FIN請求(它的接收也作為文件結束符傳遞給上層應用程序),并進入CLOSE_WAIT.
8. TIME-WAIT(客戶端)
在客戶端接收到服務端的FIN后,客戶端就發送ACK包,并進入TIME-WAIT狀態
TIME_WAIT等待狀態,這個狀態又叫做2MSL狀態,說的是在TIME_WAIT2發送了最后一個ACK數據報以后,要進入TIME_WAIT狀態,這個狀態是防止最后一次握手的數據報沒有傳送到對方那里而準備的(注意這不是四次握手,這是第四次握手的保險狀態)。這個狀態在很大程度上保證了雙方都可以正常結束。
9. LAST-ACK(服務端)
服務端已經發送FIN以后等待客戶端發送的ACK
被動關閉端一段時間后,接收到文件結束符的應用程序將調用CLOSE關閉連接。這導致它的TCP也發送一個 FIN,等待對方的ACK.就進入了LAST-ACK
10. CLOSING(客戶端)
CLOSING狀態在「同時關閉」的情況下出現。這里的同時關閉中的「同時」其實并不是時間意義上的同時,而是指的是在發送 FIN 包還未收到確認之前,收到了對端的 FIN 的情況。
11. closed(共有)
服務端在接受到ACK包后,就進入了closed的狀態。連接結束