計算機網路-tcp的三次握手與四次揮手

NewHongjay發表於2018-08-23

tcp的報文頭部的一些資訊

  • ACK:表示應答域有效,有兩個值0和1,tcp三次握手時第一次傳送時ACK為0。1表示應答域有效,反之為0。
  • Acknowledge Number:確認序號,確認序號應該是上次成功接受的序號+1,表示期望下一次收到的序號。主要用來解決不丟包的問題。(相當於表示上一次的內容成功接收到了)
  • Sequence Number:序號,表示報文中第一個位元組在傳送的資料流中的序號,解決亂序的問題。Sequence Number是跟Acknowledge Number一起使用的,舉個例子,主機1傳送了Sequence Number = x給主機2,那麼主機2收到之後就將Acknowledge Number設定為x+1,意思是這次的訊息收到了,下次主機1應該傳送的下一個Sequence Number為x+1。
  • SYN:同步序號,用來建立連線,SYN與ACK一起搭配使用,tcp第一次握手時(連線請求)SYN = 1,ACK = 0,tcp第二次握手時(響應連線)SYN = 1,ACK = 0(這個標誌的資料包經常被用來進行埠掃描。掃描者傳送一個只有SYN的資料包,如果對方主機響應了一個資料包回來 ,就表明這臺主機存在這個埠;但是由於這種掃描方式只是進行TCP三次握手的第一次握手,因此這種掃描的成功表示被掃描的機器不很安全,一臺安全的主機將會強制要求一個連線嚴格的進行TCP的三次握手)
  • FIN:表示傳送端已經達到資料末尾,也就是說雙方的資料傳送完成,沒有資料可以傳送了,傳送FIN標誌位的TCP資料包後,連線將被斷開。

image.png

  • tcp連線首先要經過三次握手來建立連線,三次握手之後成功建立連線,然後才開始進行資料的傳輸

  • 第一次握手:客戶端傳送連線請求報文段(SYN報文),將SYN設定為1,Sequence Number為x,傳送之後進入SYN_SEND狀態,等待伺服器確認


  • 第二次握手:服務端對接收到的SYN請求報文進行確認,確認SYN(設定Acknowledgement Number為 x+1(Sequence Number+1)),SYN設定為1,Sequence Number設定為y,ACK設定為1(ACK不等於Acknowledge Number),服務端將這些資訊放到一個報文段(即傳送SYN+ACK包)一起傳送給客戶端,此時進入SYN_RECV狀態

  • 第三次握手:客戶端收到伺服器的SYN+ACK報文後檢查Acknowledge Number是否正確,將Acknowledge Number設定為y+1,然後像伺服器傳送ACK報文段,這個報文段傳送完之後服務端客戶端都進入ESTABLISHED狀態,此時就完成了三次握手

為什麼要採用三次握手

image.png

  • 如果不採用三次握手,假如主動方傳送一個連線請求報文,但是由於網路原因延遲到達了請求方。但是這個請求已經失效了,於是被動方就同意連線請求等待主動方傳送資訊,但是由於這個請求已經失效,主動方不會給被動方傳送資訊,就會導致被動方一直等待而浪費資源。

tcp的四次揮手(四次分手)

  • 說明當主機之間通過三次揮手建立了連線,資料傳輸完畢之後就需要斷開連線,斷開這個過程就需要四次揮手

  • 第一次揮手:主機1設定Sequence Number ,傳送FIN報文段(請求關閉連線),之後進入FIN_WAIT_1狀態(表示主機1沒有訊息傳送了)

  • 第二次揮手:主機2收到主機1的報文之後設定Acknowledge Number同時傳送ACK報文告知對方同意對方的關閉請求,主機1(注意不是主機2)進入FIN_WAIT_2狀態,主機2會進入CLOSE_WAIT狀態。

  • 第三次揮手:主機2傳送FIN報文請求關閉連線,同時進入LAST_ACK狀態

  • 第四次分手:主機1收到主機2傳送的FIN報文段之後,像主機回覆一個ACK報文段,同時進入TIME_WAIT狀態。主機2收到這個ACK報文段之後就關閉連線。主機1在等待2MSL之後沒收到回覆表示主機2已經正常關閉連線了,那麼主機1關閉連線

  • 四次握手的幾個狀態
    • FIN_WAIT_1:在主機第一次傳送FIN報文之後就會進入這個狀態,這個跟FIN_WAIT_2狀態比較類似,表示等待對方的FIN報文。區別是當主機在連線建立時(ESTABLISHED狀態),想要主動關閉連線,就傳送一個FIN報文之後就進入FIN_WAIT_1狀態,在對方回覆了ACK報文之後就進入FIN_WAIT_2狀態,這個時候就等待對方的FIN報文。(主動方)
    • FIN_WAIT_2:FIN_WAIT_2狀態表示半連線狀態,表示一方要求關閉連線,但另外還告訴對方,我暫時還有點資料需要傳送給你(ACK資訊),稍後再關閉連線。(主動方)。 CLOSE_WAIT:在被動關閉連線情況下,在已經接收到FIN,但是還沒有傳送自己的FIN的時刻,連線處於CLOSE_WAIT狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以 close這個SOCKET,傳送FIN報文給對方,也即關閉連線。所以你在CLOSE_WAIT狀態下,需要完成的事情是等待你去關閉連線。(被動方)
    • LAST_ACK:被動的一方傳送了FIN(上面的主機2)報文之後等待對方的ACK報文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。(被動方)
    • TIME_WAIT:表示收到對方的FIN報文之後回覆ACK報文,等待2MSL之後就進入CLOSED可用狀態。如果FINWAIT1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。(主動方)
    • CLOSED:連線中斷。

為什麼要採取四次揮手

  • 主動方傳送FIN報文之後表示主動方沒有要傳送的資料但是還可以接收資料,被動方收到主動方傳送的FIN報文後回覆一個ACK報文表示被動方已經知道主動方沒有資訊傳送了,然後被動方回覆一個FIN報文表示告訴主動方被動方也沒資訊傳送了,之後主動方回覆一個ACK報文後告訴被動方收到訊息,之後兩者就能結束連線了。

相關文章