“三次握手”,參考:https://www.cnblogs.com/KongJetLin/p/13063394.html
前面進行“三次握手”建立連接后,當客戶端的資料發送完畢,它就會要求與服務器端斷開連接,那么就要進行“四次揮手”進行連接的釋放,
注意,此處所謂的“客戶端”與“服務器端”,只是為了方便標識連接的雙方,即確認哪一方是“要求斷開連接”的主動方,哪一方是“要求斷開連接”的被動方,事實上任何一方都可能在發送完資料后要求與另一方斷開連接,
1、“四次揮手”程序
如下圖:

“四次揮手”的具體程序如下:
1)“第一次揮手”:首先,客戶端已經發送完資料,想要釋放連接(客戶端是釋放連接的主動方),向服務器端發送一段TCP報文,其中:
i)標記位 FIN=1:表示這個TCP請求是“請求釋放連接”;
ii)報文的序號 seq=u:u 等于前面客戶端已經傳送的資料的最后一個位元組的序號加1;
iii)客戶端由“ESTABLISHED”連接建立狀態,進入“FIN-WAIT-1”終止等待狀態1,此時客戶端不會再向服務器端發送資料,
需要注意,FIN報文雖然不攜帶資料,但是但是它會消耗一個位元組序號,即客戶端第一次發送的FIN報文 seq=u,報文會消耗一個序號,那么客戶端下次發送的報文應該從 seq=u+1 開始發送,
2)“第二次揮手”:服務器端接收到從客戶端發出的TCP報文之后,確認了客戶端想要釋放連接,會發送回一個TCP報文,其中:
i)標記位為ACK=1:表示“服務器端告知客戶端,自己已經接收到客戶端發送的釋放連接的請求”;
ii)報文序號 seq=v:服務器端到客戶端的連接還沒有關閉,服務器端還會向客戶端發送資料包,這個報文序號為 v;
iii)確認號ack = u+1:表示希望客戶端下一個報文的序號是 u+1,即希望客戶端下一個報文從序號為 u+1 的位元組開始發送,我們知道客戶端第一個報文 seq=u,且該報文為FIN報文,占一個序號,那么客戶端下一個報文就應該從 u+1 開始發送,
iv)服務器端結束 “ESTABLISHED” 連接階段,進入“CLOSE-WAIT” 關閉等待狀態;
此時從 客戶端到服務器端 這個方向的連接就被釋放,TCP連接處于“半關閉狀態” , 此時客戶端不會再向服務器端發送資料,但是服務器端可能還會想客戶端發送資料,
v)客戶端收到從服務器端發出的TCP報文之后,確認了服務器端收到了客戶端發出的釋放連接請求,隨后客戶端結束“FIN-WAIT-1”終止等待狀態1,進入“FIN-WAIT-2”終止等待狀態2,
總結:前兩次揮手,既讓服務器端知道了客戶端想要釋放連接,也讓客戶端知道了服務器端知道了自己想要釋放連接,
3)“第三次揮手”:客戶端經過 “ClOSE-WAIT” 關閉等待 狀態后,它要發送給服務器端的資料也發送完畢,即它做好了釋放服務器端到客戶端連接的準備,就會想客戶端發送一段FIN的TCP報文:
i)標記位 FIN=1,ACK=1:表示“服務器端告知客戶端,自己已經做好釋放連接的準備”;
ii)報文序號 seq=w:關閉等待階段,服務器端可能又向客戶端發送了資料,因此此時 seq 不是v,而是最新的資料 w;
iii)確認號 ack=u+1:還是希望客戶端下一次發送的報文序號為 u+1;
iv)發送“第三次揮手”報文后,服務器端進入“LAST-ACK” 最后確認階段,此后,服務器端再也無法向客戶端發送資料,
注意,第三次揮手發送的是FIN的報文,沒有資料但是會占一個序號,即下一次服務器端發送的報文序號 seq=w+1,
4)“第四次揮手”:客戶端接收到服務器端“第三次揮手”的報文后,確認服務器端已經做好斷開連接的準備,會向客戶端發送“第四次握手”的報文:
i)標記位ACK=1:表示“客戶端已經知道服務器端做好釋放連接的準備”;
ii)ack = w+1:將收到服務器端報文的 seq+1,作為自己的ack,表示希望服務器端下次發送的報文的序號為 w+1;
iii)seq=u+1:將收到服務器端報文的 ack 作為自己的 seq,因為服務器端報文 ack=u+1 表示希望客戶端這次發送的報文序號是 u+1,那么客戶端這次發送報文的序號就設定為 u+1;
iv)客戶端發送完第四次揮手的報文后,啟動等待計時器,等待2MSL后,如果沒有收到服務器端新的請求,就進入“CLOSED” 連接關閉狀態;
v)服務器端在收到客戶端發送的第四次揮手的報文后,進入進入“CLOSED” 連接關閉狀態,
總結:后“兩次揮手”既讓客戶端知道了服務器端準備好釋放連接了,也讓服務器端知道了客戶端了解了自己準備好釋放連接了,于是,可以確認關閉服務器端端到客戶端方向上的連接了,由此完成“四次揮手”,關閉了連接,
2、三個關鍵問題
1)為什么“握手”是三次,而“揮手”卻是四次?
對于“三次握手”,在第二次握手的時候,服務器端向客戶端發送的報文的標記位包含 SYN=1以及ACK=1,SYN是請求連接標志,表示服務器端同意建立連接;ACK是確認報文,表示告訴客戶端,服務器端收到了它的請求報文,即“確認接收”與“同意連接”是在同一次握手中傳輸的,那么通過三次握手就剛剛好可以建立連接;
對于“四次揮手”,第二次揮手的時候,服務器端可能還沒有做好關閉連接的準備(它可能還有資料要發送給客戶端),因此,它不會立即釋放連接,會在第二次揮手先回傳一個ACK=1,表示已經接受到客戶端的斷開連接的請求,隨后,客戶端處理完資料后,會發送第三次揮手報文,其中FIN=1,表示服務器端已經準備好釋放連接,因此,釋放連接需要經過“四次揮手”,
2)為什么客戶端要在發送第四次揮手的報文后等待2MSL的時間才進入CLOSED狀態?
目的是為了確認服務器端會收到客戶端發送的“第四次揮手”的ACK確認報文,
MSL(Max Segment Lifetime): 最長報文段壽命,也就是一個報文在網路中存活的最長時間,一般設定為2分鐘,當客戶端發出最后的ACK確認報文時,并不能確定服務器端能夠收到該段報文,所以客戶端在發送完ACK確認報文之后,會設定一個時長為2MSL的計時器,
在1MSL的時候,如果服務器端沒有收到客戶端發送的ACK確認報文,就會再次向客戶端發送FIN報文,這個報文在1MSL的時間內會到達客戶端,此時客戶端邊知道自己上一次發送的ACK確認報文沒有發送到服務器端,于是客戶端會再次向服務器端發送ACK確認報文,并將等待計時器重置,
如果在2MSL的時間內沒有接受到服務器端發送回來的FIN報文,說明客戶端最后發送的ACK確認報文已經被服務器端接收到,可以關閉連接,因此,事實上客戶端會比服務器端更晚進入CLOSED狀態,
3)如果已經建立了連接,但是客戶端出現故障了怎么辦?
如果客戶端發送錯誤,服務器端還一直保持連接,這個連接并不會傳送資料,并且占用了服務器端的資源,服務器端有一個“保活計時器”,服務器端每收到一次客戶端的請求后都會重新復位這個計時器,時間通常是設定為2小時,若2小時還沒有收到客戶端的任何資料,客戶端就會發送一個探測報文段,以后每隔75秒鐘發送一次,若一連發送10個探測報文客戶端仍然沒反應,服務器端就認為客戶端出了故障,接著就關閉連接,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/41111.html
標籤:其他
上一篇:計算機網路-經典計算例題
下一篇:射頻識別技術RFID
