tcp爲何要三次握手

做者:大閒人柴毛毛
連接:https://www.zhihu.com/question/24853633/answer/254224088
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

TCP三次握手

PS:TCP協議中,主動發起請求的一端稱爲『客戶端』,被動鏈接的一端稱爲『服務端』。不論是客戶端仍是服務端,TCP鏈接創建完後都能發送和接收數據。服務器

起初,服務器和客戶端都爲CLOSED狀態。在通訊開始前,雙方都得建立各自的傳輸控制塊(TCB)。
服務器建立完TCB後遍進入LISTEN狀態,此時準備接收客戶端發來的鏈接請求。網絡

第一次握手
客戶端向服務端發送鏈接請求報文段。該報文段的頭部中SYN=1,ACK=0,seq=x。請求發送後,客戶端便進入SYN-SENT狀態。優化

  • PS1:SYN=1,ACK=0表示該報文段爲鏈接請求報文。
  • PS2:x爲本次TCP通訊的字節流的初始序號。
    TCP規定:SYN=1的報文段不能有數據部分,但要消耗掉一個序號。

第二次握手
服務端收到鏈接請求報文段後,若是贊成鏈接,則會發送一個應答:SYN=1,ACK=1,seq=y,ack=x+1。
該應答發送完成後便進入SYN-RCVD狀態。計算機網絡

  • PS1:SYN=1,ACK=1表示該報文段爲鏈接贊成的應答報文。
  • PS2:seq=y表示服務端做爲發送者時,發送字節流的初始序號。
  • PS3:ack=x+1表示服務端但願下一個數據報發送序號從x+1開始的字節。

第三次握手
當客戶端收到鏈接贊成的應答後,還要向服務端發送一個確認報文段,表示:服務端發來的鏈接贊成應答已經成功收到。
該報文段的頭部爲:ACK=1,seq=x+1,ack=y+1。
客戶端發完這個報文段後便進入ESTABLISHED狀態,服務端收到這個應答後也進入ESTABLISHED狀態,此時鏈接的創建完成!3d

爲何鏈接創建須要三次握手,而不是兩次握手?
防止失效的鏈接請求報文段被服務端接收,從而產生錯誤。server

PS:失效的鏈接請求:若客戶端向服務端發送的鏈接請求丟失,客戶端等待應答超時後就會再次發送鏈接請求,此時,上一個鏈接請求就是『失效的』。blog

若創建鏈接只需兩次握手,客戶端並無太大的變化,仍然須要得到服務端的應答後才進入ESTABLISHED狀態,而服務端在收到鏈接請求後就進入ESTABLISHED狀態。此時若是網絡擁塞,客戶端發送的鏈接請求遲遲到不了服務端,客戶端便超時重發請求,若是服務端正確接收並確認應答,雙方便開始通訊,通訊結束後釋放鏈接。此時,若是那個失效的鏈接請求抵達了服務端,因爲只有兩次握手,服務端收到請求就會進入ESTABLISHED狀態,等待發送數據或主動發送數據。但此時的客戶端早已進入CLOSED狀態,服務端將會一直等待下去,這樣浪費服務端鏈接資源。ip

TCP四次揮手

 

TCP鏈接的釋放一共須要四步,所以稱爲『四次揮手』。
咱們知道,TCP鏈接是雙向的,所以在四次揮手中,前兩次揮手用於斷開一個方向的鏈接,後兩次揮手用於斷開另外一方向的鏈接。資源

第一次揮手
若A認爲數據發送完成,則它須要向B發送鏈接釋放請求。該請求只有報文頭,頭中攜帶的主要參數爲:
FIN=1,seq=u。此時,A將進入FIN-WAIT-1狀態。io

  • PS1:FIN=1表示該報文段是一個鏈接釋放請求。
  • PS2:seq=u,u-1是A向B發送的最後一個字節的序號。

第二次揮手
B收到鏈接釋放請求後,會通知相應的應用程序,告訴它A向B這個方向的鏈接已經釋放。此時B進入CLOSE-WAIT狀態,並向A發送鏈接釋放的應答,其報文頭包含:
ACK=1,seq=v,ack=u+1。

  • PS1:ACK=1:除TCP鏈接請求報文段之外,TCP通訊過程當中全部數據報的ACK都爲1,表示應答。
  • PS2:seq=v,v-1是B向A發送的最後一個字節的序號。
  • PS3:ack=u+1表示但願收到從第u+1個字節開始的報文段,而且已經成功接收了前u個字節。

A收到該應答,進入FIN-WAIT-2狀態,等待B發送鏈接釋放請求。

第二次揮手完成後,A到B方向的鏈接已經釋放,B不會再接收數據,A也不會再發送數據。但B到A方向的鏈接仍然存在,B能夠繼續向A發送數據。

第三次揮手
當B向A發完全部數據後,向A發送鏈接釋放請求,請求頭:FIN=1,ACK=1,seq=w,ack=u+1。B便進入LAST-ACK狀態。

第四次揮手
A收到釋放請求後,向B發送確認應答,此時A進入TIME-WAIT狀態。該狀態會持續2MSL時間,若該時間段內沒有B的重發請求的話,就進入CLOSED狀態,撤銷TCB。當B收到確認應答後,也便進入CLOSED狀態,撤銷TCB。

爲何A要先進入TIME-WAIT狀態,等待2MSL時間後才進入CLOSED狀態?
爲了保證B能收到A的確認應答。
若A發完確認應答後直接進入CLOSED狀態,那麼若是該應答丟失,B等待超時後就會從新發送鏈接釋放請求,但此時A已經關閉了,不會做出任何響應,所以B永遠沒法正常關閉

 
 
之因此存在 3-way hanshake 的說法,是由於 TCP 是雙向通信協議,做爲響應一方(Responder) 要想初始化發送通道,必須也進行一輪 SYN + ACK。因爲 SYN ACK 在 TCP 分組頭部是兩個標識位,所以處於優化目的被合併了。因此達到雙方都能進行收發的狀態只須要 3 個分組

在謝希仁著《計算機網絡》第四版中講「三次握手」的目的是「爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤」。在另外一部經典的《計算機網絡》一書中講「三次握手」的目的是爲了解決「網絡中存在延遲的重複分組」的問題。這兩種不用的表述其實闡明的是同一個問題。 謝希仁版《計算機網絡》中的例子是這樣的,「已失效的鏈接請求報文段」的產生在這樣一種狀況下:client發出的第一個鏈接請求報文段並無丟失,而是在某個網絡結點長時間的滯留了,以至延誤到鏈接釋放之後的某個時間纔到達server。原本這是一個早已失效的報文段。但server收到此失效的鏈接請求報文段後,就誤認爲是client再次發出的一個新的鏈接請求。因而就向client發出確認報文段,贊成創建鏈接。假設不採用「三次握手」,那麼只要server發出確認,新的鏈接就創建了。因爲如今client並無發出創建鏈接的請求,所以不會理睬server的確認,也不會向server發送數據。但server卻覺得新的運輸鏈接已經創建,並一直等待client發來數據。這樣,server的不少資源就白白浪費掉了。採用「三次握手」的辦法能夠防止上述現象發生。例如剛纔那種狀況,client不會向server的確認發出確認。server因爲收不到確認,就知道client並無要求創建鏈接。
相關文章
相關標籤/搜索