計算機網路——TCP三次、四次握手詳解

weixin_34321977發表於2016-06-22

三次握手:建立TCP連線


連線建立過程:

  B的TCP伺服器程式先建立傳輸控制塊TCB(儲存了每一個連線中的一些重要資訊,如:TCP連線表,到傳送和接收快取的指標,到重傳佇列的指標,當前的傳送和接收序號,等),準備接受客戶程式的連線請求。然後伺服器程式就處於LISTEN(收聽)狀態,等待客戶的連線請求。如有,即作出相應。
  A的TCP客戶程式也是首先建立傳輸控制模組TCB,然後向B發出連線請求報文段,這時首部中的同步為SYN=1,同時選擇一個初始序號seq=x。TCP規定,SYN報文段(即SYN=1的報文段)不能攜帶資料,但要消耗掉一個序號。這時,TCP客戶程式進入SYN-SENT(同步已傳送)狀態。
  B收到連線請求報文段後,如同意建立連線,則向A傳送確認。在確認報文段中應把SYN位和ACK位都置1,確認號是ack=x+1,同時也為自己選擇一個初始序號seq=y。注意。這個報文段也不能攜帶資料,但同樣要消耗掉一個序號。這時TCP伺服器程式進入SYN-RCVD(同步收到)狀態。
  TCP客戶程式收到B的確認後,還要向B給出確認。確認報文段的ACK置1,確認號ack=y+1,而自己的序號seq=x+1。這時,TCP連線已經建立,A進入ESTABLISHED(已連線狀態)。
  當B收到A的確認後,也進入ESTABLISHED狀態。
  以上便是三次握手的流程。

問題:

  1.為什麼不可以是兩次握手?為什麼A還要傳送一次確認?

  答:主要是為了防止已失效的連線請求報文段突然又傳送到了B,因而產生錯誤。

  比如說這種異常情況:A發出的第一個連線請求報文段並沒有丟失,而是在某些網路結點長時間滯留了,以致延誤到連線釋放以後的某個時間才到達B。本來這是一個早已失效的報文段。但B收到此失效的連線請求報文段後,就誤以為是A又發出一次新的連線請求。於是就向A發出確認報文段,同意建立連線。假定不採用三次握手,那麼只要B發出確認,新的連線就建立了。

  由於現在A並沒有發出建立連線的請求,因此不會理財B的確認,也不會向B傳送資料。但B卻以為新的連線已經建立了,並一直等待A發來資料。B的許多資源就這樣被浪費。

四次握手:TCP的連線釋放


連線釋放過程:

  過程高階、複雜,複製別人的(=。=):

  中斷連線端可以是Client端,也可以是Server端。

  假設Client端發起中斷連線請求,也就是傳送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有資料要發給你了",但是如果你還有資料沒有傳送完成,則不必急著關閉Socket,可以繼續傳送資料。所以你先傳送ACK,"告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的訊息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端確定資料已傳送完成,則向Client端傳送FIN報文,"告訴Client端,好了,我這邊資料發完了,準備好關閉連線了"。Client端收到FIN報文後,"就知道可以關閉連線了,但是他還是不相信網路,怕Server端不知道要關閉,所以傳送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK後,"就知道可以斷開連線了"。Client端等待了2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,我Client端也可以關閉連線了

問題:

  1.為什麼建立連線時是三次握手,而斷開時需要四次握手?

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

相關文章