怎樣生動描述 TCP 的「三次握手」?


「你瞅啥?」
「瞅你咋地?」
「來咱倆嘮嘮。」
然後就嘮上了。


how are you ?
fine.And you?
Fine.


倆人見面,客套完確認對方正常以後,就開始工作了。


「我能給你講個關於tcp的笑話嗎?」
「行,給我講個tcp笑話.」
「好吧那我就給你講個tcp笑話.」


不要抖機靈,三次握手即是在最快最省力的情況下做出的選擇
比如在紅軍時代,A連和B連分在左右翼,約定在幾時幾分一同發起打擊。這個幾時幾分的信息就需要人工通過通訊員來走路傳遞。所以A連指揮官派出通訊員。
這是第一次。
假設通訊員到達了B連,並且告知了B連指揮官幾時幾分,B連指揮官一定會讓通訊員再回去通知A連指揮官,可憐的通訊員只能冒著危險返回A連,因為A連指揮官看不到通訊員返回的話,不知道幾時幾分這個信息到底傳達到了B連沒有。
這是第二次。
現在B連指揮官開始擔心通訊員是否回到了A連,如果沒回到,B連指揮官會設身處地的想一想A連指揮官見不到返回的通訊員,肯定是不敢打的,所以B連指揮官最盼望的是再次看到通訊員出現在B連,所以A連指揮官會讓通訊員再回B連一次。
這是第三次。
這就是三次握手


「喂喂喂,能聽到我嗎?」
「沒問題。能聽到我說一聲。」
「沒問題。」


1.約嗎
2.約
3.我出發了


A: 我們開始互相發東西玩吧,我的東西從a開始編號。
B: 收到(a+1),我的東西從b開始編號。
A: 收到(b+1)
blabla

我覺得樓上很多人貌似忽略了一個很重要的因素,那就是SYN序列號的問題。三次握手能夠確保對面已經收到自己的同步序列號,這樣就可以保證後續數據包的丟失可以被察覺,這也是TCP流式傳輸的基礎。


「報告大王!」 (SYN)
「不要叫我大王,要叫我女王大人!」 (SYN-ACK)
「好的大王!」 (ACK)
「報告大王!那老漢家就在前方!」 (DATA)


我只是出來反對最高票的答案的,他的描述明顯是不正確的。而且是嚴重誤導的。
TCP的握手,首先要明確的是必然有發起方(A)和接收方(B)。
第一次握手,必然是A向B發起的。即A向B發送了一個SYN包。如果套用高票的情境,可以理解為:"我想瞅瞅你,在嗎?"。
第二次握手,B發現有一個人試圖連接自己,那麼就回復一個ACK包表示接收連接。即"在的,你瞅吧"。
第三次握手,是A在知道B同意讓自己連接後,也向B發一個ACK包表示我已經就位。即"嗯,我已經看到你了。(隱含著意思:我接下來要一直瞅你,如果兩個都沒說走,誰也不能走。)"
我看到好多答主在看到幾個回答後瞬間就進入抖機靈模式,而且完全不管主被動的關係,也不管合理性,最後發展成看誰寫的三行短小說最好看了。
ps:高票的回答如果一定要三次握手的話,我覺得是這樣:
「 。。。」 --------------------漏了第一次握手
「你瞅啥?」 --------------------第二次握手
「瞅你咋地?」 --------------------第三次握手
「來咱倆嘮嘮。」 -------------------多餘的交互
TCP是一個喪心病狂的追求效率的協議,除非必要,絕不會有多餘的報文。


我:喵。
貓:喵。
我:喵。
貓: HTTP /1.1 200 OK


沒有一個像樣的。。。
你們忘了ACK的作用。

本來應該是這樣子的:

後來為了省流量把兩句合成一句,就成了:

「哦」相當於ACK,acknowledgement的意思,起到的是確認的作用。

順便補上斷開的四次:

等一段時間,對方不說話了才正式睡覺


A: 在嗎?
B: 在,你還在嗎?
A: 在!,那個啥啥啥啥。。。。
B: 那個啥啥啥啥。
。。。。


這問題答案很容易通過搜索引擎獲得。


三次握手是為了確認客戶端跟伺服器都能接受到對方的信息。


第一次握手,客戶端給伺服器發包。 此時伺服器確認自己可以接收客戶端的包,客戶端不確認伺服器是否接收到了自己發的包。


第二次握手,伺服器端回復客戶端。 此時客戶端確認自己發的包被伺服器收到,也確認自己可以正常接收伺服器包,客戶端對此次通信沒有疑問了。伺服器可以確認自己能接收到客戶端的包,但不能確認客戶端能否接收自己發的包。

第三次握手,客戶端回復伺服器。 客戶端已經沒有疑問了,伺服器也確認剛剛客戶端收到了自己的包。兩邊都沒有問題,開始通信。


針對評論里為什麼是三次而不是兩次四次的回答。


約?
約!
啪啪啪~


簡化三次握手流程

從圖片可以得到
三次握手可以簡化為:
C發起請求連接
S確認,也發起連接
C確認

我們再看看每次握手的作用:

第一次握手:S只可以確認 自己可以接受C發送的報文段

第二次握手:C可以確認 S收到了自己發送的報文段,並且可以確認 自己可以接受S發送的報文段

第三次握手:S可以確認 C收到了自己發送的報文段


總結:三次握手,對於每一方來說,可以確認兩個信息:
1.確認 自己可以接受對方發來的報文段
2.確認 對方收到了自己的報文
一旦這兩個得到確認,連接就建立起來了,後面才開始傳送數據

---------------------------------------------------------------------------------------
關於為什麼要三次握手,大家從握手過程也可以看得出。不過書上是這樣的解釋:

謝希仁的《計算機網路》說:防止 已失效的連接請求報文段突然又傳給server

「已失效的連接請求報文段」的產生在這樣一種情況下:client發出的第一個連接請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連接釋放以後的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認為是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不採用「三次握手」,那麼只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送ack包。(此時因為client沒有發起建立連接請求,所以client處於CLOSED狀態,接受到任何包都會丟棄,謝希仁舉的例子就是這種場景)但server卻以為新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。採用「三次握手」的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。

參考:
計算機網路 (豆瓣)
tcp為什麼要三次握手,而不能二次握手?


##都在抖激靈,沒一個好好回答的。真想理解的話看這裡啦喂~


1、唐王欲和如來建立外交,取大乘佛法普渡亡靈。便派出唐僧西去,九九八十一難還沒走完,唐王知去路艱辛,不知御弟能不能無恙抵達。

2、唐僧歷盡磨難終於抵達雷音寺,如來甚是高興,同時也明白了,大唐到我西天的來路,通了。但他卻擔心著來容易,想回萬難的情況。於是帶上真經,又讓唐僧回大唐去了。一路騰雲駕霧,師徒幾人好不快活。

3、轉眼已到大唐境內,按下祥雲,直撲唐王懷中哭訴心酸去了。唐王嘴上安慰,心裡樂道:有這真經為憑,說明我大唐到那西天,去得,也回得。少卿御弟淚止,於是大小法事,普渡亡靈。唐王甚歡,正愁如何封賞,卻得知玄奘已成正果,回西天去了。

4、如來正值焦急之際,見金蟬子轉回,隨即眉開眼笑,心裡好不自在:我這西天到那大唐,來得,也回得。這中土的香火,再不是那道家獨吃咯。


自此,西天與大唐互通有無,佛教也在中原有了立足之地,皆大歡喜。也再無人問津唐僧師徒,跑的那三趟腿。


給你們講一個案例,讓你們明白 http 協議三次握手的重要性。

上圖就是握手失敗的案例,所以永遠不可能建立穩定的通訊進行信息交換。o( ̄▽ ̄)d good


"How are you?"
"Fine thank you, and you?"
"I"m fine too."


男:妹子我喜歡你
女:我知道你喜歡我了,帥哥我也喜歡你
男:你知道我喜歡你了啊!你喜歡我我也喜歡你啊!
於是倆人就。。。。。。。。。。了


聽得見嗎
聽得見,你呢
嗯聽見,那開始吧


。。。。


推薦閱讀:

tcp協議握手為什要各隨機一個數字並加一?
在TCP里可以讓數個Application共享一個Port么?
在以TCP為連接方式的伺服器中,為什麼在服務端設計當中需要考慮心跳?
基於UDP實現的可靠傳輸協議(比如uTP),與TCP協議相比有什麼優缺點?
為什麼多 TCP 連接分塊下載比單連接下載快?

TAG:互聯網 | 計算機網路 | TCP |