怎麼理解TCP的面向連接和UDP的無連接(不面向連接)?

如題,在理解TCP和UDP中,一個是面向連接的傳輸協議,一個是不面向連接的協議。怎麼能夠更好的理解他們的不同。


亞當和夏娃分別生活在兩個山頭,山頭之間是萬丈深淵,亞當採集野果需要分享給夏娃,如果他們之間有一條索道(物理連接),野果可以順著索道滑到夏娃那一邊,那就沒有車小胖什麼事了。

事實上山頭之間沒有索道,但是亞當何等聰明,於是他想出了一個方法,假設亞當需要給夏娃10個野果,否則她會餓死。

連接建立
亞當對著夏娃大喊:愛妃,你聽得到嗎?

夏娃回應:孩他爹,我聽得到!

亞當接著喊:那好,我扔果子給你吃,你接到果子就喊一聲,一共十個。

運送貨物

於是亞當開始扔第一個,夏娃喊收到了一個。

亞當扔第二個,夏娃喊收到兩個。

超時重傳 ( timeout retransmit)

亞當扔第三個,可是夏娃遲遲沒有迴音,亞當意識到可能果子落到懸崖了,於是重新扔,夏娃喊收到第三個。

Advertised window size = 0

於是亞當連續扔了第四、五、六個,夏娃急了:孩他爹,慢點扔,臣妾忙不過來了…

Advertised window size &> 0

於是亞當坐下休息,愛妃又開始叫了:繼續扔吧。


亞當開始扔第七個,夏娃喊收到七個。

關閉連接

終於亞當扔完了,亞當喊:愛妃,果子扔完了,寡人去忙別的了。

夏娃回復:好的,我也休息一下,再見

亞當:再見

以上的過程類似TCP連接的過程,TCP是一個虛擬連接。

何為虛擬連接?

和物理連接所對應,物理連接是實實在在存在的,看得見摸得著,比如索道。而虛擬連接是不存在的,看不見摸不著,通過雙向的消息、消息確認來模擬物理連接。

由於有確認機制,亞當可以確保夏娃可以收到10個果子。

那接下來再談談什麼是無連接的UDP?

亞當和夏娃吵架了,任憑亞當如何大聲喊,夏娃躲在樹林後生悶氣,一聲不響,亞當害怕夏娃餓死,於是開始自說自話朝著夏娃的山頭扔玉米棒子:

一個、兩個、三個…

一共扔了十個,但最終扔到對方山頭到底有幾個,亞當沒有底,也許有的玉米棒子落到懸崖了,但是這個效率高啊,可以連續扔,以前扔10個果子需要一分鐘,現在只需要20秒。

亞當扔果子、扔玉米都有可能扔到懸崖下,但是扔果子為何可以確保對方收到十個?那是因為夏娃收到一個果子,然後喊收到了,如果沒有收到,亞當就重新扔,直到夏娃說收到了。而扔玉米棒子對方沒有確認,所以對於丟棄的情況無法知道,也無法重新扔。


「我給你講一個關於TCP的笑話。」
「好的你給我講一個關於TCP的笑話。」
「好的。」
「苟。這是第一個字。」
「第一個字收到,請發第二個字。」
「利。這是第二個字。」
「第二個字收到,請發第三個字。」
「國。這是第三個字。」
「國。這是第三個字。」
「第三個字收到,請發第四個字。」
「家……」
……
「我講完了。」
「好的。我聽完了。」
「好的。」

「我給你講一個關於UDP的笑話。」
「咦我好像聽見一個關笑P話的U……?咦這苟啊國家啊這什麼什麼之是啥玩意?我讓應用層看看……應用層說應該是兩句詩?」


看了一下,大部分回答都把 面向連接 和 可靠傳輸 兩件事情混為一談了。

連接是為了標誌「專有」,而不是為了可靠。
同一對埠上可以有複數個TCP通訊,TCP協議本身可以區分不同的數據屬於哪一組通訊。
UDP做不到這點,因為它是無連接的。


面向連接就類似打電話,無連接就類似寫信。

補充:
Tcp中可以把一次相關數據的傳輸過程看成是一次連接,如telnet一次登錄過程。
開始傳輸數據前要建立連接,如果建立失敗則不能傳數據。
結束時要釋放連接。
在這次傳輸過程中,雙方的TCP會對數據進行處理,如編號,確認重傳等,從而保證傳輸滿足下列特點:
(1)雙方向,即全雙工
(2)可靠的,即出錯能檢測出來並處理
(3)按順序的,即收發順序一致
(4)數據流式的,即不是面向數據包的,應用程序不知道包邊界
(5)可唯一標識,即通過雙方埠號,IP地址這四個數字唯一標識一次連接過程


TCP:
A:「Hi,你老公下午在家嗎?」
B:「不在呀,他出差去了!」
A:「那我下午去你家!嘿嘿嘿♀」
下午:
"咚咚咚~"
B:「還好你早上打了電話,他上午還在家」

UDP:
「咚咚咚~」
C:「好啊!原來就是你!自己居然送上門來了!」

---------------------------------------------------------------
上面只是個不太恰當的比喻,簡單來說TCP關心分組是否準確送達,甚至仔細到給每個分組編號並收到目的端的確認「我已經收到啦~你繼續發~」才繼續發送後續的分組,而UDP則不然,它只負責把分組封裝好後直接發送到鏈路上,至於目的端收到與否並不關心
對於「面向連接」和「非面向連接」,面向連接必須在建立連接前確認雙方鏈路可達並已準備好才開始通信,而非面向連接則是發送端在開始通信前也不去詢問接收端是否可達並已準備好接收數據。就好比上面的例子,A得確認去B家裡很安♂全♀才動身前往,不然就會像後面的例子一樣。
不過需要說明的是,雖然經常提到TCP的可靠性比UDP高,但是這並不說明UDP就沒有可靠性,本身「可靠性」就是從多方面來衡量的,使用UDP的分組僅僅在傳輸層使用可靠性較低的方式傳輸,但是具體到業務,一些上層協議依然能彌補可靠性這一環。而且,在較優的鏈路上或對及時性要求較高的應用,使用TCP協議反而會降低網路或者應用性能,例如在Windows遠程桌面里,如果遠程的計算機在同一個內網內,可以點擊網路質量的按鈕,會彈出一個msg「與遠程計算機的連接良好,並已啟用UDP」


按照我們計算機網路老師的撩妹理論來推:

TCP就是你約你心儀的妹子出來,告訴她你喜歡她。

UDP就是你告訴你心儀妹子的閨密和朋友,你喜歡那個妹子。

(感覺這個例子並不是很好,還是看書吧,反正都在第一/二章...)

想起一件事兒,前幾天,同學去面一家遊戲公司,面試官問:「你是不是很喜歡打LOL?」「是」「那你認為你打遊戲的過程中用到了TCP還是UDP呢?」


TCP和UDP,協議的目的是為了兩端進行對話。有連接和無連接就像打電話和發簡訊。一個要先撥通,而另一個只要有號碼就行。
有連接
A撥電話:滴…滴…滴…(如果此時語音提示你撥打的電話無法接通則直接掛掉,通信中斷)
B接電話:小王您好,我是老宋,有什麼事情。
A:balabala
無連接
A發簡訊:balabala

TCP的面向連接指對話之前需要先建立一個會話,而UDP無連接直接發送消息
再補充一個有確認和無確認,有確認無確認與有連接無連接沒有必然聯繫。有無確認區別主要在消息發送出去之後。

有確認
A:balabala
A:怎麼不說話,你聽不到嗎?那我重說一次。balabala
B:現在聽到了
A:好的,繼續。balabala
無確認
A:balabala

無論是有連接還是無連接,對話時都可以使用有確認和無確認的方式進行對話。


接吻與飛吻,這是我當時在課上聽老師說出其區別後的第一反應


TCP協議是一種可靠的通信協議,它要求傳輸的過程是可靠的,因此需要經過三次握手的環節,確立連接關係之後,才可以進行傳輸。除此之外,TCP還有超時重傳機制,還有排序的機制,有發送的窗口,有窗口大小等等,保證接收方接收到的就是發送方發送過去的。

UDP是一種不可靠的通信協議,它不需要建立連接,不需要對連接進行確認ACK的操作,不需要重傳,不需要排序,它只管傳輸。

TCP傳輸就像打電話,兩邊要喊「喂」,確保雙方都聽到的情況下,才說內容,如果某句話對方沒有聽清楚,對方會要求你重新說一次,直至對方清楚為止,打電話就是要雙方說的每一句話都清清楚楚,而且收聽者邏輯和意思是和講話者保持一致的。

UDP傳輸就像寄信,我只管把信寫好,只管把信投到信箱里,至於投到信箱之後,郵遞員什麼時候來取,多少天到達,郵遞員在郵遞的過程中會不會弄丟,我是沒有辦法控制的,我能做的,只是把這封信投出去。


你花錢僱傭一個人幫你送快遞,這是tcp
你寫了地址包裹,直接往快遞中轉站一扔,這是udp


tcp相當於電話,udp相當於簡訊。前者時刻保持鏈接狀態,一旦信號不好,連接中斷,需要重連才能繼續通信。後者,則不管你有沒有開機,有沒有信號,直接丟給你,也不管你有沒有收到。


簡單的說,就像拉煤,如果用有軌火車拉,必須在兩地間建好鐵路,然後二十多個車廂連接在一起,在一個軌道上走,按順序到達目的地,基本上不可能出現順序改變或者車廂丟失的事,火車可以一直通行直到鐵道部游擊隊拆掉它為止,這就是有連接的tcp。

如果用貨車拉,就不一樣了,不用建鐵軌,隨時隨地可以出發,幾十部車走的路徑可能不同,速度不同,到達目的的時間也不同,導致到達的順序可能發生變化,甚至可能出現某些車在半路歇菜或者被某個山大王劫持到不了目的地的情況,這就是無連接的udp 。


簡單點說,tcp寄丟了至少告訴你一句寄丟了,如果可能還幫你重試下,udp寄出去就寄出去了,丟了就丟了。
tcp就是個挂號信,udp是平信,在網路高度發展的今天,大家都不缺錢,tcp貴是貴了點,但大家都喜歡用


這個用工具驗證下就看出來了。(用Wireshark · Go Deep.)
tcp:
0、使用Wireshark,輸入過濾

tcp.port == 20000

1、打開簡單的tcp伺服器:

nc -l 20000

2、客戶端連接20000埠

nc 127.0.0.1 20000

3、在客戶端輸入test,然後ctrl+c關閉連接(注意:伺服器端也關閉了)。
4、查看結果

UDP:
0、使用Wireshark,輸入過濾

udp.port == 20000

1、打開簡單的udp伺服器:

nc -u -l 20000

2、客戶端連接20000埠

nc -u 127.0.0.1 20000

3、在客戶端輸入test,然後ctrl+c關閉連接。(注意:伺服器端還正常)
4、查看


tcp就是你在村東頭給在村西頭的小花打電話,你說的她能聽到同時你也知道她能聽到。。。。

udp就是你在村東頭用大喇叭喊話,小花她可能聽得到也可能聽不到,你們村的人都有可能聽到,你不知道她聽不聽得到。。。。


Tcp 通訊之前需要建立連接,通訊完成需要關閉連接,通過重傳等機制確保對端能完整收到。
Udp 通訊什麼都不需要,只管往外發。對端收不收的到無法得知。

Tcp 建立連接,又稱三次握手
A:我喜歡你
B:我也喜歡你
A:那咱們在一起吧

Tcp 關閉連接,又稱四次揮手
A:咱們分手吧
B:你確定嗎?
B:那好吧,再見
A:再見

Udp 傳輸數據
A:我喜歡你
B:....(沒有回應)


這個問題我問過不少人,招聘的時候。其實這裡涉及到一個基本概念「連接」。理解了什麼是連接(網路連接),就能回答本問題了。
網路連接本質上是信息發送與應答,只要發出信息,就能收到答覆,否則重發,直到超時,則認為斷開連接;也可以主動發送斷開連接的信息,對方收到後也要回答。


趁午休答一波,其實是要根據應用選擇不同協議,TCP/UDP只是第四層,上面應用層協議要求才決定下層協議是否面對鏈接。上學的時候,老師就一句是否面對鏈接來區分這兩個協議。實際工作中,像4G核心網中,很多用到diameter協議,其下層就是TCP,因為需要知道彼此埠號和角色,確保偶聯,進行彼此間數據的可靠傳輸,優點是能確保這條連路連通,缺點是佔用資源。而像GTP協議的下層,就是UDP,只需要確保消息發出去,能收到回復就行(發一次丟包就多發幾次),優點就是省事,占的資源小。


有握手(控制交換)的是Tcp,
沒有的是UDP


TCP需要握手連接,UDP直接發送,你可以從任何一本關於socket編程中找到二者的編程流程,從流程上看,TCP需要調用更多的連接,監聽的函數,而UDP初始化後便可直接發送數據,這就可以驗證,Tcp是有連接的,UDP 木有有。


推薦閱讀:

tcp 握手後向公網發送包,與mss大小不符合,丟失問題?
IPv6是否有FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF這個地址?
為什麼我的網易雲音樂客戶端無法聯網?
如何突破校園網網速限制?
如何防止自己被人肉搜索到?

TAG:互聯網 | 計算機網路 | 計算機科學 | TCPIP | 網路協議 |