TCP四次揮手

過程如下:

捕獲.PNG

1)主機A發送位碼爲FIN=1,用來關閉客戶A到服務器B的數據傳送。此時A的狀態爲FIN_WAIT_1 
2)服務器B收到這個FIN,它發回一個ACK,確認序號爲收到的序號加1。此時A爲FIN_WAIT_2,B爲CLOSE_WAIT 
3)服務器B關閉與客戶端A的連接,發送一個FIN給客戶端A。此時A爲TIME_WAIT,B爲LAST_ACK 
4)客戶端A發回ACK報文確認,並將確認序號設置爲收到序號加1。此時A、B都關閉了,狀態變爲CLOSED。 
當(2)、(3)步中的ACK和FIN在一個包中發送時,A的狀態會直接從FIN_WAIT_1變爲TIME_WAIT 


爲什麼建立連接需要三次握手,而斷開連接需要四次握手?

  因爲每個方向都需要一個FIN和ACK,當一端發送了FIN包之後,處於半關閉狀態,此時仍然可以接收數據包。 

  在建立連接時,服務器可以把SYN和ACK放在一個包中發送。 

  但是在斷開連接時,如果一端收到FIN包,但此時仍有數據未發送完,此時就需要先向對端回覆FIN包的ACK。等到將剩下的數據

都發送完之後,再向對端發送FIN,斷開這個方向的連接。 

  因此很多時候FIN和ACK需要在兩個數據包中發送,因此需要四次握手 


中各種狀態的含義

FIN_WAIT_1: 這個狀態要好好解釋一下,其實 FIN_WAIT_1 和 FIN_WAIT_2 狀態的真正含義都是表示等待對方的 FIN 報文。而這兩

種狀態的區別是:FIN_WAIT_1 狀態實際上是當 SOCKET 在 ESTABLISHED 狀態時,它想主動關閉連接,向對方發送了 FIN 報文,此

時該 SOCKET 即進入到 FIN_WAIT_1 狀態。而當對方迴應 ACK 報文後,則進入到 FIN_WAIT_2 狀態,當然在實際的正常情況下,無

論對方何種情況下,都應該馬 上回應 ACK 報文,所以 FIN_WAIT_1 狀態一般是比較難見到的,而 FIN_WAIT_2 狀態還有時常常可

以用 netstat 看到。


FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上 FIN_WAIT_2 狀態下的 SOCKET,表示半連接,也即有一方要求 close 連接,但

另外還告訴對方,我暫時還有點數據需要傳送給你,稍後再關閉連接。


TIME_WAIT: 表示收到了對方的 FIN 報文,併發送出了 ACK 報文,就等 2MSL 後即可回到 CLOSED 可用狀態了。如果 FIN_WAIT_1 

狀態下,收到了對方同時帶 FIN 標誌和ACK 標誌的報文時,可以直接進入到 TIME_WAIT 狀態,而無須經過 FIN_WAIT_2 狀態。


CLOSING(圖中沒有標誌這種狀態): 這種狀態比較特殊,實際情況中應該是很少見,屬於一種比較罕見的例外狀態。正常情況下,當

你發送 FIN 報文後,按理來說是應該先收到(或同時收到)對方的 ACK 報文,再收到對方的 FIN 報文。但是 CLOSING 狀態表示

你發送 FIN 報文後,並沒有收到對方的 ACK 報文,反而卻也收到了對方的 FIN 報文。什麼情況下會出現此種情況呢?其實細想一

下,也不難得出結論:那就是如果雙方幾乎在同時close一個 SOCKET 的話,那麼就出現了雙方同時發送 FIN 報文的情況,也即會出

現 CLOSING 狀態,表示雙方都正在關閉 SOCKET 連接。



CLOSE_WAIT: 這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方 close 一個 SOCKET 後發送 FIN 報文給自己,你係統毫

無疑問地會迴應一個 ACK 報文給對方,此時則進入到 CLOSE_WAIT 狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還

有數據發送給對方,如果沒有的話,那麼你也就可以 close 這個 SOCKET,發送 FIN 報文給對方,也即關閉連接。所以你在 CLOSE_WAIT

 狀態下,需要完成的事情是等待你去關閉連接。


LAST_ACK: 這個狀態還是比較容易好理解的,它是被動關閉一方在發送 FIN 報文後,最後等待對方的 ACK 報文。當收到 ACK 報文後

,也即可以進入到 CLOSED 可用狀態了。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章