TCP 為什麼是三次握手,而不是兩次或四次?

時間 2021-05-06 21:23:28

1樓:xuanweiace

一些簡單好記的結論:

首先明確一點,傳送方傳送的資料報包含資料,才需要進行ack確認(且必須進行ack確認),而如果傳送方傳送的只是ack確認而無資料,則無需再次確認(不然就會無限迴圈)。

所有的重傳,都由傳送方負責,接收方不負責。

何時觸發重傳?傳送方在超時器計時結束後仍然沒有收到ack確認,則觸發傳送方的重傳。

何為傳送方?主動傳送資料的為傳送方。(理論上只發ack的不能叫傳送方吧,只能算是接收方發給傳送方的ack確認罷了)

設傳送方為A,接收方為B

如果A傳送的是資料,且一直沒有收到ack確認,則會一直重發該資料。因為他需要對丟失該資料報負責(不管是因為A--資料-->B這條路丟包了還是 B--ack-->A這條路丟包了)

B發ack回來的時候,一定不會涉及重發啥的,因為他不對丟失資料報負責(因為如果A沒收到B的確認,會再發一次資料報的)。所以B作為只發ack的那方,不用管這個ack到沒到。他只需要負責:

收到A的資料報就發一次確認就完事了。至於丟包與否都是A(傳送方)的事情。

握手本身也應該是四次,只不過2,3次合起來了,所以該協議中,B給A傳送的不只是ack了,還有資料,所以在握手中,需要A再發一次ack(此時B是傳送方,A是接收方了)

而因為A這次只傳送的ack,按照我們剛剛說的約定,只傳送ack的不需要確認,所以三次握手就可以結束。

至於為什麼兩次握手不行,因為這樣違背了上面定義的結論:傳送方傳送的是資料,則必須進行ack確認。此時B作為傳送方,當然需要A傳送確認。

關於tcp連線的問題我是經歷了無數次的「以為自己懂了」->「發現還是迷糊」->「以為自己徹底懂了」->「發現思路還是不清晰」的過程。

這次靜下心看了一些回答,我總結了下:定義好傳送方和接收方,並且設定幾個規則,那麼思路就非常清晰了,直接把我自己給看懂了,我笑了。

我覺得再難的情況出現,也能用上述規則去解釋的明明白白。

2樓:ikmOfSA

我也是來學習的,看了其他答主的答案,做下總結。

TCP連線建立的過程,實際上是乙個Client/Server雙方同步的過程,同步即指「我要開始傳送資料了,我也知道你做好了準備」。

為什麼要「知道對方做好了準備」?舉個例子,如果Server沒有做好準備(如沒有分配buffer等資源),那Client傳送過去的資料會被丟棄,就造成資源浪費,不是最優解。

前「兩次握手」很好理解,針對「第三次握手」:如果沒有來自Client的確認,以Server的視角,不知道Client是否知道了自己的sequence number(比如Client可能根本沒收到「第二次握手」的SYNACK);此時如果Server貿然傳送資料,可能不會被接收,從而造成資源浪費。

這裡的關鍵在於,「第二次握手」時,Server產生了新的資訊(比如其sequence number),而且這個資訊是關係到Client的,因此需要Client再確認一次,即「第三次握手」; 否則,假設Server沒有新的資訊或者其資訊跟Client無關,那麼Client完全可以在「第一次握手」時就提前準備好,就可以化簡為「兩次握手」。

3樓:三土土門人

我覺得兩次握手應該可行。第一次握手,客戶端給服務端傳送SYN為1的、不帶資料的報文,第二次握手,服務端給客戶端傳送SYN為1的、可以攜帶資料的報文。此時服務端認為已經建立了連線,可以向客戶端傳送報文了。

舉個例子。首先是客戶端向服務端傳送乙個資料為空、SYN為1的、序列號為789的報文,然後服務端向客戶端傳送乙個資料可以不為空、SYN為1、序列號為123的報文,此時服務端認為已經建立了連線,可以接著傳送SYN為0、資料不為空序列號為124、125、126的報文。

假如第二次握手服務端傳送的報文123丟失了,客戶端由於沒有收到SYN為1的報文,所以認為沒有建立連線,即使收到了124、125、126也不確認,超時後客戶端就重新傳送789。客戶端又收到了乙個SYN為1的報文,就重發123。客戶端收到了重發的123,於是以123為起點建立滑動視窗,開始等待後面的報文。

服務端的124、125、126也會因為沒收到回應報文而重發,這樣客戶端就能收到124、125、126並確認了。

這種握手機制的問題,其實就是教科書中寫的,在上一次連線關閉後,客戶端的第一次握手的報文又傳送到客戶端時,客戶端會進行第二次握手,並且認為已經建立了連線,等待客戶端傳送報文,造成資源的浪費。所以需要使用第三次握手。

4樓:assassin chen

前提:如果雙方都能確認對方可以收到自己的訊息,那麼就可以建立TCP連線了。

因為要確認對方已經收到了自己發出去的訊息。

比如最後一次客戶端發給服務端的訊息,如果服務端沒收到客戶端發的確認訊息, 服務端就無法判斷客戶端能否收到服務端的訊息。

後者最後一次握手不進行,即使客戶端收到了來自服務端的訊息,那麼也只是客戶端確認服務端收到了自己之前發出的訊息,但是服務端還是無法確認自己發出的訊息能不能被客戶端接收到。所以建立兩次握手是不行的,進行三次握手後,雙方都可以確認對方能收到自己的訊息,那麼就可以建立TCP連線了。

為什麼不需要四次握手?

經過三次握手雙方都可以確認對方能接收到自己發出的訊息,這個時候資訊就可以放心的傳遞給對方了,沒必要再進行第四次握手,進行第四次握手是多餘的。

雙方都能確認對方能收到自己發出的訊息表明對方是可靠的,後續可以大膽放心的傳遞資料給對方,就不怕對方收不到我發出去的資料啦

經過上述分析就可以理解為什麼TCP採用三次握手策略,就是為了準確無誤地將資料送達目標處

5樓:CoderLi

張三和李四想進行一次交流,那麼他們首先是不是要確認下面的事情之後、才能夠進行交流

張三和李四都要確定:張三說的話李四能聽到

張三和李四都要確定:李四說的話張三能聽到

第一次握手之後、李四能確定張三說的話他能聽到第二次握手之後、張三能確定他說的話李四能收到、張三能確定李四的話他能收到

第三次握手之後、李四能確定他說的話張三能收到所以基本通訊條件已經滿足了、就無須進行第四次握手了。

而如果只進行兩次握手、那麼李四就不能確定他說的話張三能不能收到了、這就會讓李四懷疑自己

6樓:YIFEI

看了各位大佬的回答,簡單總結一下:

三次握手本質上是要建立乙個對序列號的共識(雙方對一件事情共同認可),因為之後要保證資料的可靠和順序。

四次握手有點多餘,可以簡化:

四次握手是這樣的:

client>>server:SYN=a

client<>server:ACK=b+1

前兩次握手,雙方對client的序號產生了共識,後兩次握手,雙方對server的序號產生共識,這樣tcp雙向的傳輸通道建立。第二次和第三次握手可以直接放一塊傳送,這樣簡化為三次就可以了。

兩次握手不夠,會出問題:

兩次握手:

client>>server:SYN=a

client<

(1)如果第二次握手的資料丟失了,server會以為成功建立了連線,但是client沒有收到確認,所以會嘗試重新傳送SYN請求。server收到第二次SYN請求,以為是要再次建立連線就回覆ACK,於是server就維護兩個連線了。這樣二次握手可能會導致server端單方面建立許多並不成功的連線。

(2)如果第一握手的資訊package1在網路中滯留了,client檢測超時後會重新傳送SYN,server回覆ACK確認,這樣成功建立連線了。但這時已經失效的package1又到達了server,server不知道這是失效的請求,又會回覆ACK建立連線。當client接收到第二個ACK,知道server端用失效的SYN建立了連線,只能乾著急。

7樓:黃夢召

1.客戶發出,伺服器接收,此時伺服器知道客戶端有傳送的能力,但是不知道客戶端有沒有接收的能力

2.伺服器發出,客戶端接收,此時客戶端知道伺服器有接收和傳送的能力3.客戶端再傳送,伺服器接收。此時伺服器也知道了客戶端受到了他剛剛發的資訊,表示客戶端確實有接收的能力

只有驗證了這些,通訊才可以正式開始

8樓:天空

兩次握手保證了單向傳輸,

「你聽的到嗎」

我聽的到」(沒有第二次的SYN,沒法確定S端的傳送是否能被接收)「你說今天會不會下雨」

「你倒是說話啊」

「你啞巴嗎」

9樓:誰殺死了知更鳥

TCP: ---- 建立可靠的連線(握手)

先明確一點:TCP報文包含多個字段,如SYN, seq, ack......如下圖

首先,伺服器開啟監聽埠,然後客戶端傳送請求;此時客戶端進入SYN-SENT狀態,即同步-傳送狀態。

第一步的字段中:SYN=1的報文不攜帶資料,但消耗乙個序號seq, x(例如012...)

然後,伺服器監聽到該請求字段,返回乙個字段。此時伺服器進入SYN-RCVD狀態,即同步-已接收狀態。

第二步欄位中:同樣,SYN=1的報文不攜帶資料,消耗乙個序號seq, y. 並返回乙個ACK=1報文,值為1代表接受到了客戶端的請求。

後面的ack=x+1含義是:希望客戶端返回乙個序號seq為x+1的報文。

接下來,客戶端收到伺服器的返回字段,再返回給伺服器乙個再次確認字段。此時客戶端進入ESTABLISHED狀態,即建立連線狀態。

第三步欄位中:包含乙個ACK=1欄位,表示客戶端收到伺服器的請求。並且seq=x+1, 因為上一步的伺服器欄位ack=x+1,要求客戶端返回seq=x+1.

然後客戶端再傳送乙個ack=y+1, 即要求下一次伺服器的seq=y+1。

最後,伺服器接收到第三步的字段,進入ESTABLISHED狀態,即建立連線狀態。

至此,三次握手完成,客戶端和伺服器之間可以進行資料傳輸。

為什麼不是兩次或者四次?

四次情況:

看圖:到第三步的時候,客戶端已經知道伺服器擁有( 接受√ 傳送√ ) 功能

伺服器也知道客戶端擁有(接受√ 傳送√)功能。第四步完全多餘

兩次情況:

看圖,當第二次握手完成時,伺服器收到了客戶端的第一次請求,並返回乙個確認字段。

如果此時建立連線,伺服器實際上並不知道客戶端是否收到了剛才返回的確認字段。

也即伺服器不知道客戶端是否具有接受能力。因此,TCP需要三次握手。

TCP建立連線的三次握手階段為什麼要協商乙個隨機的初始序列號(ISN),而不是預設從0開始

cccchan 通訊雙方在傳送SYN建立連線之前,必須為該TCP連線選定乙個ISN。ISN必須隨時變化,以確保每個連線的ISN都不一樣,尤其是相同連線 Socket 的不同例項,ISN絕不能一樣。RFC 793規定,應該使用乙個長度為32 bit並且每4s 1的計數器來選定ISN。然而,一旦有人掌握...

描述TCP建立連線的三次握手過程,如果最後一次握手失敗會怎樣處理?

參考文章 What if a TCP handshake segment is lost?In other words,if the ACK is dropped but the next packet is not dropped,then everything is fine.意思是說客戶端發出...

如果 TCP 協議中三次握手不攜帶序列號,會造成什麼樣的後果?

之所以需要三次握手,其實就是要雙方相互確認彼此能夠通訊。一般要與對方確認可以通訊,就要確認自己能夠跟對方通訊 1 且能夠收到對方的通訊 2 反過來對方也能夠和自己通訊 3 且能收到自己的通訊 4 基於這一點,流程就簡化為3次握手通訊。首先,client傳送乙個SYN 1,seq X X隨機 到ser...