TCP三報文握手和四報文揮手

三報文“握手”

在這裏插入圖片描述

TCP規定:SYN=1的報文段\color{red}{不能攜帶數據}。普通的TCP報文段可以攜帶數據,但如果不攜帶數據,則不消耗序號。

  1. 最初,客戶端 和 服務器 都是處於\color{red}{關閉狀態}。TCP服務器進程首先\color{red}{創建傳輸控制塊},用來存儲TCP鏈接中的一些重要信息,之後就準備接受TCP客戶進程的連接請求。此時,TCP服務器進程就會進入\color{red}{監聽狀態},等待客戶的請求。TCP服務器進程是被動等待來自TCP客戶進程的連接請求,而不是主動發起,因此稱爲\color{red}{被動打開連接}
  2. TCP客戶進程也是首先建立連接控制塊,然後向TCP服務器發送TCP\color{red}{TCP連接請求報文段}[SYN=1, seq=x],並進入同步已發送狀態,稱爲\color{red}{主動打開連接}SYN=1表明這是一個TCP鏈接請求報文段,序號字段seq=x,作爲TCP客戶進程所選擇的初始序號。
  3. TCP服務器進程收到客戶端發來的連接請求報文段後,如果同意建立連接,則向TCP客戶進程發送TCP\color{red}{TCP連接確認報文段}[SYN=1, ACK=1, seq=y, ack=x+1],並進入同步已接收狀態。SYN=1, ACK=1表明這是一個TCP連接請求確認報文段,seq=y作爲TCP服務器進程所選擇的初始序號,ack=x+1這是對TCP客戶進程所選擇的初始序號的確認。
  4. TCP客戶進程收到TCP連接請求確認報文段後,還要向TCP服務器進程發送一個TCP\color{red}{普通的TCP確認報文段}[ACK=1, seq=x+1, ack=y+1],並\color{red}{進入連接已建立狀態}ACK=1表明這是一個普通的TCP確認報文段,序號字段seq=x+1是因爲TCP客戶進程發送的第一個TCP報文段的序號爲x,並且不攜帶數據。確認段ack=y+1是對TCP服務器進程所選擇的初始序號的確認。TCP服務器進程收到該確認報文段後也進入\color{red}{連接已建立狀態}.

幾個問題?

可不可以只握手兩次?即不發送最後一次的普通TCP確認報文段

\color{red}{不可以}。假設TCP客戶進程發出一個TCP連接請求報文段,但該報文段在某些網絡結點長時間滯留了,這必然會造成對該報文段的超時重傳。假設重傳的報文段被TCP服務器進程正常接收,TCP服務器進程向TCP客戶進程發送一個TCP連接請求確認報文段,並進入\color{red}{連接已建立狀態}。由於這是已經改爲兩報文握手,因此TCP服務器進程發送完TCP連接請求確認報文段後,進入的是連接已建立狀態,而不像三報文握手那樣進入同步已接收狀態。TCP客戶進程收到連接請求確認報文段後也進入連接建立狀態。現在TCP雙方都處於連接已建立狀態,它們可以相互傳輸數據,之後再通過四報文揮手來釋放連接,TCP雙方都進入關閉狀態。\color{red}{一段時間後},之前滯留在網絡中失效的TCP連接請求報文段到達了TCP服務器進程,TCP服務器進程會誤認爲這是TCP客戶進程又發起了一個新的TCP連接請求,於是給TCP客戶進程發送TCP連接請求確認報文段,並進入連接已建立狀態。該報文段到達TCP客戶進程,由於TCP客戶進程實際上沒有發送新的TCP連接請求,並且處於關閉狀態,因此不會理會該報文段。但是TCP服務器進程已經進入了連接已建立狀態,他認爲新的TCP鏈接已經建立好了,並一直等待TCP客戶進程發來數據,這將白白浪費TCP服務器進程所在主機的很多資源!

如果採用的是三次握手,就算那一次失效的報文傳送過來了,服務器收到了失效的報文並回復了確認報文,但是客戶端不會再次發出確認。由於服務器收不到確認,就知道客戶端並沒有請求連接。

四報文“揮手”

在這裏插入圖片描述

TCP規定:終止位FIN=1的報文段即使不攜帶數據,也要消耗一個序號。

  1. TCP客戶進程主動關閉TCP連接,TCP客戶進程會發送TCP連接釋放報文段[FIN=1, seq=u],並進入終止等待-1狀態。seq=uu=+1u = 結束報文段序號+1FIN=1是終止報文段。
  2. 服務器接收到客戶端發來的FIN包之後,會發送一條普通的TCP確認報文段[ACK=1, seq=v, ack=u+1],並進入關閉等待狀態。ACK=1表明這是一個普通的TCP確認報文段,序號seq=v中的 v 等於TCP服務器進程之前已傳送過的數據的最後一個字節的序號加1,確認段ack=u+1是對TCP連接釋放報文段的確認。TCP服務器進程會告訴高層應用進程,TCP客戶進程要斷開與自己的TCP連接。此時,從TCP客戶進程到TCP服務器進程這個方向的連接就釋放了。這時TCP連接屬於半關閉狀態,即TCP客戶進程沒有數據要發送了,但TCP服務器進程如果有數據要發送,TCP客戶進程仍要接收。從TCP服務器進程到TCP客戶進程這個方向的連接並未關閉
  3. TCP客戶進程收到TCP服務器進程的確認段後,進入終止等待-2狀態。TCP服務器進程發送TCP連接釋放報文段[FIN=1, ACK=1, seq=w, ack=u+1],並進入\color{red}{最後確認狀態}FIN=1, ACK=1表明這是TCP連接釋放報文段,同時也對之前收到的報文段進行確認。seq=w是對之前TCP客戶進程發送數據的字節序號。ack=u+1這是對之前收到的TCP連接釋放報文段額重複確認。
  4. TCP客戶進程收到上面報文段後,又對TCP服務器進程發送一個普通的TCP確認報文段[ACK=1, seq=u+1, ack=w+1],之後進入時間等待狀態。ACK=1表明這是普通的TCP確認報文段,序號seq=u+1是因爲TCP客戶進程之前發送的TCP連接釋放報文段雖然不攜帶數據,但要消耗一個序號。確認段ack=w+1這是對所收到的TCP連接釋放報文段的確認。TCP服務器進程收到該報文段後就進入關閉狀態,而TCP客戶進程還要經過2MSL後才能進入關閉狀態。MSL是最長報文段壽命,建議爲2分鐘。

幾個問題?

爲什麼客戶進程最後要等待2MSL時間?

防止客戶進程最後發去的 ACK 沒傳送到服務器,如果服務器沒收到客戶端的 ACK,肯定會選擇重發一次 FIN 包,那麼此時如果客戶端已經關閉了,客戶端就不能再發 ACK 確認收到了。這會造成TCP服務器進程反覆重傳TCP連接釋放字段,無法進入關閉狀態。2MSL等待時長可以確保收到最後一個服務器發送的TCP確認報文段而進入關閉狀態。另外TCP客戶進程再經歷2MSL時間就可以使本次連接所產生的所有報文段都從網絡中消失。

爲什麼不能三次揮手呢?

  • 首先如果去掉最後一次揮手,那麼服務器端就不知道自己要關閉的確認報文有沒有傳輸成功,可能半路上就失敗了,但是此時客戶端不知道,導致客戶端一直在等待服務器關閉,但是此時服務器端直接就關閉了;

如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。

  • 服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲2小時。
  • 若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。

。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。


寫的好的文章:https://blog.csdn.net/qzcsu/article/details/72861891

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章