問題:TCP連接的四次揮手

四次揮手

先明確幾個關鍵字:

同步 SYN :synchronous。建立連接,將 SYN = 1。
序號 seq :sequence。第一個字節(jié)的編號隨機產(chǎn)生。
確認位 ACK: acknowledgement 。
ack :表示確認字段的值。
結(jié)束 FIN : finish。FIN = 1 表示希望斷開連接。
重置RST:重置。

四次揮手

  • 第一次揮手:
    客戶端向服務器端發(fā)送一段TCP報文,其中:標記位為FIN,序號為Seq=u;隨后客戶端進入FIN-WAIT-1階段,即半關閉階段。并且停止在客戶端到服務器端方向上發(fā)送數(shù)據(jù),但是客戶端仍然能接收從服務器端傳輸過來的數(shù)據(jù)。
    注意:這里不發(fā)送的是正常連接時傳輸?shù)臄?shù)據(jù)(非確認報文),而不是一切數(shù)據(jù),所以客戶端仍然能發(fā)送ACK確認報文。

  • 第二次揮手:
    服務器端收到客戶端發(fā)出的FIN標記位的TCP報文之后,結(jié)束ESTABLISHED階段,進入CLOSE-WAIT階段(半關閉狀態(tài))并返回一段TCP報文,其中:標記位為ACK,序號為Seq=v;確認號為ack=u+1,表示是在收到客戶端報文的基礎上,將其序號Seq值加1作為本段報文確認號ack的值;
    隨后服務器端開始準備釋放服務器端到客戶端方向上的連接。
    客戶端收到從服務器端發(fā)出的TCP報文之后,結(jié)束FIN-WAIT-1階段,進入FIN-WAIT-2階段
    前"兩次揮手"既讓服務器端知道了客戶端想要釋放連接,也讓客戶端知道了服務器端了解了自己想要釋放連接的請求。于是,可以確認關閉客戶端到服務器端方向上的連接了

  • 第三次揮手:
    服務器端自從發(fā)出ACK確認報文之后,經(jīng)過CLOSED-WAIT階段,做好了釋放服務器端到客戶端方向上的連接準備,再次向客戶端發(fā)出一段TCP報文,其中:
    標記位為FIN,ACK,表示“已經(jīng)準備好釋放連接了”。注意:這里的ACK并不是確認收到服務器端報文的確認報文。
    序號為Seq=w,確認號為Ack=U+1表示是在收到客戶端報文的基礎上,將其序號Seq值加1作為本段報文確認號Ack的值。
    隨后服務器端結(jié)束CLOSE-WAIT階段,進入LAST-ACK階段。并且停止在服務器端到客戶端的方向上發(fā)送數(shù)據(jù),但是服務器端仍然能夠接收從客戶端傳輸過來的數(shù)據(jù)。

  • 第四次揮手:
    客戶端收到從服務器端發(fā)出的TCP報文,確認了服務器端已做好釋放連接的準備,結(jié)束FIN-WAIT-2階段,進入TIME-WAIT階段,并向服務器端發(fā)送一段報文,其中:
    標記位為ACK表示“接收到服務器準備好釋放連接的信號”。
    序號為Seq=U+1表示是在收到了服務器端報文的基礎上,將其確認號Ack值作為本段報文序號的值。
    確認號為Ack=W+1表示是在收到了服務器端報文的基礎上,將其序號Seq值作為本段報文確認號的值。
    隨后客戶端開始在TIME-WAIT階段等待2MSL

為什么“握手”是三次,“揮手”卻要四次?

TCP建立連接時之所以只需要"三次握手",是因為在第二次"握手"過程中,服務器端發(fā)送給客戶端的TCP報文是以SYN與ACK作為標志位的。SYN是請求連接標志,表示服務器端同意建立連接;ACK是確認報文,表示告訴客戶端,服務器端收到了它的請求報文。即SYN建立連接報文與ACK確認接收報文是在同一次"握手"當中傳輸?shù)模?三次握手"不多也不少,正好讓雙方明確彼此信息互通。TCP釋放連接時之所以需要“四次揮手”,是因為FIN釋放連接報文與ACK確認接收報文是分別由第二次和第三次"握手"傳輸?shù)摹?/p>

為何建立連接時一起傳輸,釋放連接時卻要分開傳輸?

  • 建立連接時,被動方服務器端結(jié)束CLOSED階段進入“握手”階段并不需要任何準備,可以直接返回SYN和ACK報文,開始建立連接。
  • 釋放連接時,被動方服務器,突然收到主動方客戶端釋放連接的請求時并不能立即釋放連接,因為還有必要的數(shù)據(jù)需要處理,所以服務器先返回ACK確認收到報文,經(jīng)過CLOSE-WAIT階段準備好釋放連接之后,才能返回FIN釋放連接報文。
為什么存在TIME_WAIT狀態(tài),要等2MSL?
  • 1.可靠的終止TCP連接
    為的是確認服務器端是否收到客戶端發(fā)出的ACK確認報文當客戶端發(fā)出最后的ACK確認報文時,并不能確定服務器端能夠收到該段報文。所以客戶端在發(fā)送完ACK確認報文之后,會設置一個時長為2MSL的計時器。MSL指的是Maximum Segment Lifetime:一段TCP報文在傳輸過程中的最大生命周期。2MSL即是服務器端發(fā)出為FIN報文和客戶端發(fā)出的ACK確認報文所能保持有效的最大時長。服務器端在1MSL內(nèi)沒有收到客戶端發(fā)出的ACK確認報文,就會再次向客戶端發(fā)出FIN報文;
  • 如果客戶端在2MSL內(nèi),再次收到了來自服務器端的FIN報文,說明服務器端由于各種原因沒有接收到客戶端發(fā)出的ACK確認報文??蛻舳嗽俅蜗蚍掌鞫税l(fā)出ACK確認報文,計時器重置,重新開始2MSL的計時;
  • 否則客戶端在2MSL內(nèi)沒有再次收到來自服務器端的FIN報文,說明服務器端正常接收了ACK確認報文,客戶端可以進入CLOSED階段,完成“四次揮手”。
    所以,客戶端要經(jīng)歷時長為2SML的TIME-WAIT階段;這也是為什么客戶端比服務器端晚進入CLOSED階段的原因
    1. 保證讓遲來的TCP報文段有足夠的時間被識別并丟棄
      在Linux系統(tǒng)上,一個TCP端口不能被同時打開多次(兩次及以上),當一個TCP連接處于TIME_WAIT狀態(tài)時,我們將無法立即使用該連接占著的端口來建立一個新連接。反過來想,如果不存在TIME_WAIT狀態(tài),則應用程序能夠建立一個和剛剛關閉的連接相似的連接(指相同的IP地址和端口號),這個新的連接被稱為原來的連接的化身(incarnation)。新的化身連接可能會接收到屬于原來連接的攜帶應用數(shù)據(jù)的TCP報文段(遲到的報文段),這顯然是不應該發(fā)生的。這是TIME_WAIT狀態(tài)存在的第二個原因。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容