TCP傳輸的三次握手與四次揮手策略

在這裏插入圖片描述
從圖片可以得到三次握手可以簡化爲:C發起請求連接S確認,也發起連接C確認
每次握手的作用:

first:S只可以確認自己可以接受C發送的報文段
second:C可以確認 S收到了自己發送的報文段,並且可以確認自己可以接受S發送的報文段
third:S可以確認 C收到了自己發送的報文段

考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認爲連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認爲連接還未建立成功,將忽略S發來的任何數據分組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖。

一、爲了準確無誤地把數據送達目標處,TCP採用了三次握手策略:

  • first:用TCP把數據包發送出去後,TCP不會對傳送後的數據置之不理,它一定會向對方確認是否成功送達。握手過程中使用了TCP的標誌,即SYN和ACK。

  • second:發送端首先給接收端發送一個帶SYN標誌的數據包。接收端收到後,回傳一個帶有SYN/ACK標誌的數據包以表示正確傳達,並確認信息。

  • third:最後,發送端再回傳一個帶ACK標誌的數據包,代表“握手”結束。

:若在握手過程中的某個階段莫名中斷,TCP會再次以相同的順序發送相同的數據包。

二、斷開一個TCP連接則需要“四次揮手”:

  • first:主動關閉方發送一個FIN,用來關閉主動關閉方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方,主動關閉方已經不會再給被動關閉方發送數據了(當然,在FIN包之前發送出去的數據,如果沒有收到對應的ACK確認報文,主動關閉方依然會重發這些數據),但是,此時主動關閉方還可以接收數據。

  • second:被動關閉方收到FIN包後,給對方發送一個ACK,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號)。

  • third:被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,被動關閉方的數據也發送完了,不會再給主動關閉方發送數據了。

  • fourth:主動關閉方收到FIN後,給被動關閉方發送一個ACK,確認序號爲收到序號+1,至此,完成四次揮手。

常見面試題

【問題1】爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?

  • 當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。
  • 但在關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

【問題2】爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

  • 在揮手結束時需要Client發送一個最後的ACK應答報文,但這個ACK報文可能會丟失。

  • 如果Server沒有收到這個ACK報文,它將不斷重複發送FIN片段,因此Client不能立即關閉,它需要確定Server接收到了該ACK。

  • Client會在發送出ACK之後進入TIME_WAIT狀態,Client會設置一個計時器,等待2MSL的時間。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回覆所需的最大時間。

  • 如果在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL;如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP連接。

【問題3】爲什麼不能用兩次握手進行連接?

  • 第三次是爲了防止出現死鎖現象。

解釋:客戶端給服務端發送一個連接請求報文,服務端收到後會回傳給客戶端一個確認應答報文;但服務端在回傳的過程中,若出現了該確認應答報文丟失的情況,則之前的連接請求報文就將失效,客戶端將不知道服務端是否已準備好,不知道服務端建立什麼樣的序列號,客戶端甚至懷疑服務端是否收到自己的連接請求分組。在這種情況下,客戶端認爲連接還未建立成功,將忽略服務端發來的任何數據分組,只等待連接確認應答分組。而服務端在發出的分組超時後,重複發送同樣的分組,出現死鎖現象。

  • 客戶端有可能因爲網絡阻塞等原因會發送多個請求報文,這時服務器就會建立連接,浪費掉許多服務器的資源。

解釋:客戶端發出的第一個連接請求報文段並沒有丟失,而是在某些網絡結點長時間滯留了,一直延遲到連接釋放以後的某個時間纔到達服務器,本來這是一個早已失效的報文段。但服務器收到此失效的連接請求報文段後,就誤認爲是客戶端又發出一次新的連接請求,於是就向客戶端發出確認報文段,同意建立連接。假定不採用三次握手,那麼只要服務端發出確認,新的連接就建立了,這樣一直等待客戶端發來數據,服務端的許多資源就浪費了。

【問題4】如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

  • TCP還設有一個保活計時器,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。

  • 服務器每收到一次客戶端的請求後都會復位這個計時器,時間通常是設置爲兩小時。若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。

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