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...