原作者:MeloDev,本文由即時通訊網重新修訂釋出,感謝原作者的無私分享。
1、前言
對于即時通訊開者新手來說,在開始着手編寫IM或消息推送系統的代碼前,最頭疼的問題莫過于到底該選TCP還是UDP作為傳輸層協定。本文延續《網絡程式設計懶人入門》系列文章的風格,通過快速對比分析 TCP 和 UDP 的差別,來幫助即時通訊初學者快速了解這些基礎的知識點,進而在IM、消息推送等網絡通信應用場景中能準确地選擇合适的傳輸層協定。
另一篇文章《
簡述傳輸層協定TCP和UDP的差別》也闡述了類似的内容,希望能為您提供更多的參考。
(本文同步釋出于:
http://www.52im.net/thread-1160-1-1.html)
2、系列文章
本文是系列文章中的第4篇,本系列文章的大綱如下:《
網絡程式設計懶人入門(一):快速了解網絡通信協定(上篇)》
網絡程式設計懶人入門(二):快速了解網絡通信協定(下篇) 網絡程式設計懶人入門(三):快速了解TCP協定一篇就夠 網絡程式設計懶人入門(四):快速了解TCP和UDP的差異》(本文)
3、參考資料
TCP/IP詳解-
第11章·UDP:使用者資料報協定 第17章·TCP:傳輸控制協定 第18章·TCP連接配接的建立與終止 第21章·TCP的逾時與重傳 通俗易懂-深入了解TCP協定(上):理論基礎 通俗易懂-深入了解TCP協定(下):RTT、滑動視窗、擁塞處理 理論經典:TCP協定的3次握手與4次揮手過程詳解 理論聯系實際:Wireshark抓包分析TCP 3次握手、4次揮手過程 技術往事:改變世界的TCP/IP協定(珍貴多圖、手機慎點) 計算機網絡通訊協定關系圖(中文珍藏版) 高性能網絡程式設計(一):單台伺服器并發TCP連接配接數到底可以有多少 高性能網絡程式設計(二):上一個10年,著名的C10K并發連接配接問題 高性能網絡程式設計(三):下一個10年,是時候考慮C10M并發問題了 高性能網絡程式設計(四):從C10K到C10M高性能網絡應用的理論探索 不為人知的網絡程式設計(一):淺析TCP協定中的疑難雜症(上篇) 不為人知的網絡程式設計(二):淺析TCP協定中的疑難雜症(下篇) 不為人知的網絡程式設計(三):關閉TCP連接配接時為什麼會TIME_WAIT、CLOSE_WAIT 不為人知的網絡程式設計(四):深入研究分析TCP的異常關閉 不為人知的網絡程式設計(五):UDP的連接配接性和負載均衡 不為人知的網絡程式設計(六):深入地了解UDP協定并用好它 UDP中一個包的大小最大能多大? 為什麼QQ用的是UDP協定而不是TCP協定? 移動端即時通訊協定選擇:UDP還是TCP?4、建立連接配接方式的差異
4.1 TCP
說到 TCP 建立連接配接,相信大多數人腦海裡肯定可以浮現出一個詞,沒錯就是--“三次握手”。TCP 通過“三次握手”來建立連接配接,再通過“四次揮手”斷開一個連接配接。在每次揮手中 TCP 做了哪些操作呢?
流程如下圖所示(TCP的三次握手和四次揮手):上圖就從用戶端和服務端的角度,清楚的展示了 TCP 的三次握手和四次揮手。可以看到,當 TCP 試圖建立連接配接時,三次握手指的是用戶端主動觸發了兩次,服務端觸發了一次。
我們可以先明确一下 TCP 建立連接配接并且初始化的目标是什麼呢?是以三次握手的次序是這樣子的:1)初始化資源;
2)告訴對方我的序列号。
1)client端首先發送一個SYN包告訴Server端我的初始序列号是X;
2)Server端收到SYN包後回複給client一個ACK确認包,告訴client說我收到了;
3)接着Server端也需要告訴client端自己的初始序列号,于是Server也發送一個SYN包告訴client我的初始序列号是Y;
4)Client收到後,回複Server一個ACK确認包說我知道了。
其中的 2 、3 步驟可以簡化為一步,也就是說将 ACK 确認包和 SYN 序列化包一同發送給 Client 端。到此我們就比較簡單的解釋了 TCP 建立連接配接的“三次握手”。
4.2 UDP
我們都知道 TCP 是面向連接配接的、可靠的、有序的傳輸層協定,而 UDP 是面向資料報的、不可靠的、無序的傳輸協定,是以 UDP 壓根不會建立什麼連接配接。
就好比發短信一樣,UDP 隻需要知道對方的 ip 位址,将資料報一份一份的發送過去就可以了,其他的作為發送方,都不需要關心。
(關于TCP的3次握手和4次揮手文章,可詳見《
》、《
》)
5、資料發送方式的差異
關于 TCP、UDP 之間資料發送的差異,可以展現二者最大的不同之處:TCP: 由于 TCP 是建立在兩端連接配接之上的協定,是以理論上發送的資料流不存在大小的限制。但是由于緩沖區有大小限制,是以你如果用 TCP 發送一段很大的資料,可能會截斷成好幾段,接收方依次的接收。 UDP: 由于 UDP 本身發送的就是一份一份的資料報,是以自然而然的就有一個上限的大小。那麼每次 UDP 發送的資料報大小由哪些因素共同決定呢?
1)UDP協定本身,UDP協定中有16位的UDP封包長度,那麼UDP封包長度不能超過2^16=65536;
2)以太網(Ethernet)資料幀的長度,資料鍊路層的MTU(最大傳輸單元);
3)socket的UDP發送緩存區大小。
先來看第一個因素,UDP 本身協定的封包長度為 2^16 - 1,UDP 標頭占 8 個位元組,IP 協定本身封裝後標頭占 20 個位元組,是以最終長度為: 2^16 - 1 - 20 - 8 = 65507 位元組。
隻看第一個因素有點理想化了,因為 UDP 屬于不可靠協定,我們應該盡量避免在傳輸過程中,資料包被分割。是以這裡有一個非常重要的概念 MTU -- 也就是最大傳輸單元。
在 Internet 下 MTU 的值為 576 位元組,是以在 internet 下使用 UDP 協定,每個資料報最大的位元組數為: 576 - 20 - 8 = 548
(有關UDP協定的最大包長限制,詳見《
6、資料有序性的差異
我們再來談談資料的有序性。
6.1 TCP
對于 TCP 來說,本身 TCP 有着逾時重傳、錯誤重傳、還有等等一系列複雜的算法保證了 TCP 的資料是有序的,假設你發送了資料 1、2、3,則隻要發送端和接收端保持連接配接時,接收端收到的資料始終都是 1、2、3。
6.2 UDP
而 UDP 協定則要奔放的多,無論 server 端無論緩沖池的大小有多大,接收 client 端發來的消息總是一個一個的接收。并且由于 UDP 本身的不可靠性以及無序性,如果 client 發送了 1、2、3 這三個資料報過來,server 端接收到的可能是任意順序、任意個數三個資料報的排列組合。
7、可靠性的差異
其實大家都知道 TCP 本身是可靠的協定,而 UDP 是不可靠的協定。
7.1 TCP
TCP 内部的很多算法機制讓他保持連接配接的過程中是很可靠的。比如:TCP 的逾時重傳、錯誤重傳、TCP 的流量控制、阻塞控制、慢熱啟動算法、擁塞避免算法、快速恢複算法 等等。是以 TCP 是一個内部原理複雜,但是使用起來比較簡單的這麼一個協定。
7.2 UDP
UDP 是一個面向非連接配接的協定,UDP 發送的每個資料報帶有自己的 IP 位址和接收方的 IP 位址,它本身對這個資料報是否出錯,是否到達不關心,隻要發出去了就好了。
是以來研究下,什麼情況會導緻 UDP 丢包:資料報分片重組丢失: 在文章之前我們就說過,UDP 的每個資料報大小多少最合适,事實上 UDP 協定本身規定的大小是 64kb,但是在資料鍊路層有 MTU 的限制,大小大概在 5kb,是以當你發送一個很大的 UDP 包的時候,這個包會在 IP 層進行分片,然後重組。這個過程就有可能導緻分片的包丢失。UDP 本身有 CRC 檢測機制,會抛棄掉丢失的 UDP 包; UDP 緩沖區填滿: 當 UDP 的緩沖區已經被填滿的時候,接收方還沒有處理這部分的 UDP 資料報,這個時候再過來的資料報就沒有地方可以存了,自然就都被丢棄了。
8、使用場景總結
在文章最後的一部分,聊聊 TCP、UDP 使用場景。
先來說 UDP 的吧,有很多人都會覺得 UDP 與 TCP 相比,在性能速度上是占優勢的。因為 UDP 并不用保持一個持續的連接配接,也不需要對收發包進行确認。但事實上經過這麼多年的發展 TCP 已經擁有足夠多的算法和優化,在網絡狀态不錯的情況下,TCP 的整體性能是優于 UDP 的。
那在什麼時候我們非用 UDP 不可呢?對實時性要求高: 比如實時會議,實時視訊這種情況下,如果使用 TCP,當網絡不好發生重傳時,畫面肯定會有延時,甚至越堆越多。如果使用 UDP 的話,即使偶爾丢了幾個包,但是也不會影響什麼,這種情況下使用 UDP 比較好; 多點通信: TCP 需要保持一個長連接配接,那麼在涉及多點通訊的時候,肯定需要和多個通信節點建立其雙向連接配接,然後有時在NAT環境下,兩個通信節點建立其直接的 TCP 連接配接不是一個容易的事情,而 UDP 可以無需保持連接配接,直接發就可以了,是以成本會很低,而且穿透性好。這種情況下使用 UDP 也是沒錯的。
以上我們說了 UDP 的使用場景,在此之外的其他情況,使用 TCP 準沒錯。
(原文連結:
點此進入,有改動)
附錄:更多網絡程式設計資料
Java新一代網絡程式設計模型AIO原理及Linux系統AIO介紹 NIO架構入門(一):服務端基于Netty4的UDP雙向通信Demo示範 NIO架構入門(二):服務端基于MINA2的UDP雙向通信Demo示範 NIO架構入門(三):iOS與MINA2、Netty4的跨平台UDP雙向通信實戰 NIO架構入門(四):Android與MINA2、Netty4的跨平台UDP雙向通信實戰 P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介 P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解 P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解 通俗易懂:快速了解P2P技術中的NAT穿透原理 >> 更多同類文章 ……