1. 程式人生 > 其它 >TCP三次握手

TCP三次握手

7. TCP怎麼連線的

三次握手

  1. Client將標誌位SYN置為1,隨機產生一個值seq=J,並將該資料包傳送給Server,等待Server確認。
  2. Server收到資料包後由標誌位SYN=1知道Client請求建立連線,Server將標誌位SYN和ACK都置1,ack=J+1,隨機產生一個值seq=K,並將該資料包發給Client以確認連線請求。
  3. Client收到確認後,檢測ack是否為J+1,ACK是否為1,如果正確則將標誌位ACK置為1,ack=K+1,並將該資料包傳送給Server。完成三次握手,隨後Client與Server之間可以開始傳輸資料了。

8. 為什麼要三次,兩次會帶來什麼問題

不能兩次

假如只進行兩次握手,客戶端傳送連線請求後,會等待伺服器端的應答。但是會出現的問題是,假如客戶端的SYN遲遲沒有到達伺服器端,此時客戶端超時後,會重新發送一次連線,假如重發的這次伺服器端收到了,且應答客戶端了,連線建立了。

但是建立後,第一個SYN也到達服務端了,這時服務端會認為這是一個新連線,會再給客戶端傳送一個ACK,這個ACK當然會被客戶端丟棄。但是此時伺服器端已經為這個連線分配資源了,而且伺服器端會一直維持著這個資源,會造成資源浪費。

兩次握手的問題在於伺服器端不知道SYN的有效性,所以如果是三次握手,伺服器端會等待客戶端的第三次握手,如果第三次握手遲遲不來,伺服器端就會釋放相關資源

為什麼連線的時候是三次握手,關閉的時候卻是四次握手?

建立連線時因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。所以建立連線只需要三次握手。

由於TCP協議是一種面向連線的、可靠的、基於位元組流的運輸層通訊協議,TCP是全雙工模式
這就意味著,關閉連線時,當Client端發出FIN報文段時,只是表示Client端告訴Server端資料已經發送完畢了。當Server端收到FIN報文並返回ACK報文段,表示它已經知道Client端沒有資料傳送了,但是Server端還是可以傳送資料到Client端的,所以Server很可能並不會立即關閉SOCKET,直到Server端把資料也傳送完畢。
當Server端也傳送了FIN報文段時,這個時候就表示Server端也沒有資料要傳送了,就會告訴Client端,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次TCP連線。

為什麼要等待2MSL?

MSL:報文段最大生存時間,它是任何報文段被丟棄前在網路內的最長時間。
有以下兩個原因:

    • 第一點:保證TCP協議的全雙工連線能夠可靠關閉
      由於IP協議的不可靠性或者是其它網路原因,導致了Server端沒有收到Client端的ACK報文,那麼Server端就會在超時之後重新發送FIN,如果此時Client端的連線已經關閉處於CLOESD狀態,那麼重發的FIN就找不到對應的連線了,從而導致連線錯亂,所以,Client端傳送完最後的ACK不能直接進入CLOSED狀態,而要保持TIME_WAIT,當再次收到FIN的收,能夠保證對方收到ACK,最後正確關閉連線。
    • 第二點:保證這次連線的重複資料段從網路中消失
      如果Client端傳送最後的ACK直接進入CLOSED狀態,然後又再向Server端發起一個新連線,這時不能保證新連線的與剛關閉的連線的埠號是不同的,也就是新連線和老連線的埠號可能一樣了,那麼就可能出現問題:如果前一次的連線某些資料滯留在網路中,這些延遲資料在建立新連線後到達Client端,由於新老連線的埠號和IP都一樣,TCP協議就認為延遲資料是屬於新連線的,新連線就會接收到髒資料,這樣就會導致資料包混亂。所以TCP連線需要在TIME_WAIT狀態等待2倍MSL,才能保證本次連線的所有資料在網路中消失。