天天看點

三次握手和四次揮手_TCP的三次握手、四次揮手

前面介紹了TCP協定是OSI參考模型中傳輸層的代表協定,是以TCP協定是為了保障通信可靠性的,那具體TCP協定是如何保障通信可靠性的呢?那就是TCP協定通過“三次握手”的建立連接配接的方式和“四次揮手的”斷開連接配接的方式保障的。

1、三次握手

實體層、資料鍊路層在實體層面上架設好了通信鍊路,網絡層确定了通信雙方的位址,那下一步就是傳輸層建立邏輯層面上的通信連接配接,将從應用層獲得的封包資料從源端發送給接受端。TCP的三次握手就是在發送資料前通過“三次握手”的方式建立起這個通信連接配接,

建立這個連接配接的目的是讓源端和目的端确認一下雙方的發送封包能力和接收封包能力是正常的,實際上就是通過三次握手這個操作将下面的表填完整:
三次握手和四次揮手_TCP的三次握手、四次揮手

圖1.1 三次握手要填充的表格

下面具體介紹三次握手的過程,并在每次握手時填充這個表格,當表格填滿後,意味着源端和目的端已确認完畢雙方的發送封包能力和接收封包能力是正常的,三次握手結束,通信雙方的連接配接已成功建立。

1.1 TCP封包首部

在介紹三次握手前先介紹一下TCP封包的首部,封包首部可以了解為封包的中繼資料,裡面存放着與這次封包相關的其他資訊,圖我就不擺了,介紹一下跟三次握手相關的封包首部字段。

(1)序号seq

對位元組流的編号。例如第一個位元組的序号為 301,如果攜帶的資料長度為 100 位元組,那麼下一個封包段的序号應為 401。注意第一份封包段的序号是随機生成的,後面的封包段序号是根據上一個封包段序号及封包長度生成的。

(2)确認号ack

期望收到的下一個封包段的序号。例如 B 正确收到 A 發送來的一個封包段,序号為 501,攜帶的資料長度為 200 位元組,是以 B 期望下一個封包段的序号為 701,B 發送給 A 的确認封包段中确認号就為 701。

(3)SYN

控制位的一種,用于建立連接配接,該位設為 1,表示希望建立連接配接,并對第一份封包的序号進行随機初始化。

(4)ACK

控制位的一種,确認應答的字段有效,TCP規定除了最初建立連接配接時的 SYN 包以外該位必須設為 1。

(5)FIN

控制位的一種,當FIN=1,表明此封包的發送方的資料已經發送完畢,要求關閉連接配接。

1.2 三次握手具體過程

TCP三向交握的過程如圖所示,圖來自連接配接3。

三次握手和四次揮手_TCP的三次握手、四次揮手

圖1.2 TCP三向交握過程

(1)第一次握手

Client端将SYN置為1,表示希望與Server端建立連接配接;序号seq初始化為J,并将該資料包發送給Server端,Client進入SYN_SENT狀态,等待Server确認。

(2)第二次握手

Server端檢查封包發現SYN為1,知道了Client端想建立連接配接;Server端将SYN置為1,表示Server端也希望與Clinet端建立連接配接;Server端将ACK置為1,表示收到了Client端建立連接配接的請求;Server端将seq初始化為K;Server端将ack置為J+1,這裡ack=seq + 1,還有疑問(如果控制位占1位元組,為什麼第三次握手時有ACK=1、SYN=1,ack為什麼不是+2?如果+1隻是告訴服務端收到了消息,那ACK控制位就已經達到目的了,為什麼還要多次一舉再加一個ack?)。第二次握手包括服務端确認用戶端發來的封包和服務端向用戶端發送封包兩個過程。

第二次握手時表格填充結果如下:

三次握手和四次揮手_TCP的三次握手、四次揮手

圖1.3 第二次握手表格填充

(3)第三次握手

Client收到封包後,檢查ack是否為J+1,ACK是否為1,如果正确則将标志位ACK置為1,ack=K+1,并将該資料包發送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正确則連接配接建立成功,Client和Server進入ESTABLISHED狀态,完成三次握手,随後Client與Server之間可以開始傳輸資料了。第三次握手包括用戶端确認服務端發來的封包,用戶端向服務端發送封包和服務端确認用戶端發來的封包三個過程。

第三次握手用戶端确認資訊後填充表格如下:

三次握手和四次揮手_TCP的三次握手、四次揮手

圖1.4 第三次握手用戶端确認資訊表格填充

第三次握手服務端确認資訊後填充表格如下:

三次握手和四次揮手_TCP的三次握手、四次揮手

圖1.5 第三次握手服務端确認資訊表格填充

至此,表格填充完畢,三次握手也結束,連接配接成功建立。有些面試官會問為什麼不是2次握手?因為2次握手表格填充不完,源端和目的端無法确認雙方的收發能力;為什麼不是4次握手?3次握手表格就填充完畢了,不需要再多一次握手了。

2、四次揮手

三次握手是建立TCP連接配接,四次揮手是斷開TCP連接配接,即用戶端和服務端總共要收發4個包才能确定斷開連接配接。

2.1 四次揮手的具體過程

四次揮手的過程如圖所示,圖摘自連接配接4:

三次握手和四次揮手_TCP的三次握手、四次揮手

圖2.1 TCP四次揮手過程圖

(1)第一次揮手

假設用戶端主動發起斷開請求,用戶端向服務端發送封包,封包首部包括FIN=1,這個控制位代表用戶端想要斷開連接配接;序列号seq=u,這時用戶端進入FIN-WAIT-1(終止等待1)狀态,停止發送資料,并等待服務端的确認。

(2)第二次揮手

服務端收到用戶端的封包後發出确認封包,控制位ACK=1;确認号ack=u+1;序列号seq=v;然後服務端就進入CLOSE-WAIT(關閉等待)狀态。TCP服務端會告知上層的應用程序來自用戶端的連接配接即将關閉,讓應用程式做好相應的準備。此時用戶端已經沒有資料向服務端發送了,但服務端向用戶端發送資料,用戶端依然能接收。

(3)第三次揮手

用戶端收到伺服器确認封包後,進入FIN-WAIT-2狀态。此時伺服器再次發送封包,封包首部控制位FIN=1,表示服務端向用戶端發送斷開連接配接請求;确認标志ACK=1;确認序号ack=u+1;序号seq=w,然後伺服器進入LAST-ACK(最後确認态),等待用戶端确認。

(4)第四次揮手

用戶端收到了服務端的斷開連接配接的封包後,必須發出确認封包,标志位ACK=1;确認号ack=w+1;序号seq=u+1;之後用戶端就進入了TIME-WAIT(時間等待)狀态。注意此時用戶端的TCP連接配接還沒有釋放,必須經過2*MSL(最長封包段壽命)的時間後,用戶端才進入CLOSED狀态關閉連接配接。而服務端隻要收到了用戶端發送的确認封包後就會進入CLOSED狀态關閉服務端連接配接。當用戶端和服務端都進入了CLOSED狀态後,用戶端和服務端之間的連接配接才完全斷開。

2.2 為什麼會有TIME_WAIT狀态?

上面介紹第四次揮手的過程中,用戶端在發送完給服務端的回執封包後沒有立刻進入CLOSED狀态,而是進入TIME-WAIT狀态,然後等待2*MSL(最長封包段壽命)的時間後才進入CLOSED狀态,這是為什麼?原因有以下兩點:

  • 用戶端發送給服務端回執後,有可能這個回執封包在傳輸途中丢失等原因,服務端并沒有收到,此時服務端會再次向用戶端發送FIN=1的斷開請求封包,如果用戶端沒有等待2*MSL時間而直接進入了CLOSED狀态,用戶端就會收不到服務端再次發送的斷開連接配接的請求封包,導緻服務端無法進入CLOSED狀态;
  • 等待一段時間是為了讓本連接配接持續時間内所産生的所有封包都從網絡中消失,使得下一個新的連接配接不會出現舊的連接配接請求封包。

注:MSL是Maximum Segment Lifetime英文的縮寫,中文可以譯為“封包最大生存時間”,他是任何封包在網絡上存在的最長時間,超過這個時間封包将被丢棄。

2.3 為什麼是四次揮手而不是三次或者五次?

第二次揮手和第三次揮手都是服務端向用戶端發送封包,第二次揮手是服務端收到了用戶端的斷開請求,通知用戶端俺收到了,此時用戶端沒有資料向服務端發送了,但不代表服務端也沒有資料向用戶端發送,因為服務端要把剩餘還沒有發送的封包發送完畢再斷開連接配接;第三次揮手是服務端資料全部發送完畢,向用戶端發送斷開請求封包(FIN=1)。

如果是三次揮手,即把服務端向用戶端發送封包的第二次揮手和第三次揮手合為一次,會造成服務端發送了回執後立刻又發送斷開請求,造成服務端有資料沒有全部發送至用戶端,是以必須将第二次揮手和第三次揮手分開;五次揮手則完全沒必要,多此一舉。

參考

herongwei:一文搞定 UDP 和 TCP 高頻面試題!​zhuanlan.zhihu.com

三次握手和四次揮手_TCP的三次握手、四次揮手

為什麼三次握手的時候ack=seq+1_網絡_oldfish_C的部落格-CSDN部落格​blog.csdn.net

三次握手和四次揮手_TCP的三次握手、四次揮手

簡述TCP的三次握手過程 - 清風木 - 部落格園​www.cnblogs.com

三次握手和四次揮手_TCP的三次握手、四次揮手

TCP三向交握和四次揮手通俗了解 - jainss - 部落格園​www.cnblogs.com

三次握手和四次揮手_TCP的三次握手、四次揮手

繼續閱讀