快速理解TCP和UDP的差別

前言

最頭疼的問題莫過於到底該選TCP仍是UDP做爲傳輸層協議。經過快速對比分析 TCP 和 UDP 的區別,來幫助即時通信初學者快速瞭解這些基礎的知識點,從而在IM、消息推送等網絡通訊應用場景中能準確地選擇合適的傳輸層協議。算法

創建鏈接方式的差別

TCP

說到 TCP 創建鏈接,相信大多數人腦海裏確定能夠浮現出一個詞,沒錯就是--「三次握手」。TCP 經過「三次握手」來創建鏈接,再經過「四次揮手」斷開一個鏈接。在每次揮手中 TCP 作了哪些操做呢?緩存

流程以下圖所示(TCP的三次握手和四次揮手):網絡

clipboard.png

上圖就從客戶端和服務端的角度,清楚的展現了 TCP 的三次握手和四次揮手。能夠看到,當 TCP 試圖創建鏈接時,三次握手指的是客戶端主動觸發了兩次,服務端觸發了一次。socket

咱們能夠先明確一下 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 創建鏈接的「三次握手」。spa

UDP

咱們都知道 TCP 是面向鏈接的、可靠的、有序的傳輸層協議,而 UDP 是面向數據報的、不可靠的、無序的傳輸協議,因此 UDP 壓根不會創建什麼鏈接。視頻

就比如發短信同樣,UDP 只須要知道對方的 ip 地址,將數據報一份一份的發送過去就能夠了,其餘的做爲發送方,都不須要關心。server

數據發送方式的差別

關於 TCP、UDP 之間數據發送的差別,能夠體現兩者最大的不一樣之處:ip

  • TCP:
    因爲 TCP 是創建在兩端鏈接之上的協議,因此理論上發送的數據流不存在大小的限制。可是因爲緩衝區有大小限制,因此你若是用 TCP 發送一段很大的數據,可能會截斷成好幾段,接收方依次的接收。
  • UDP:
    因爲 UDP 自己發送的就是一份一份的數據報,因此天然而然的就有一個上限的大小。

那麼每次 UDP 發送的數據報大小由哪些因素共同決定呢?

  • UDP協議自己,UDP協議中有16位的UDP報文長度,那麼UDP報文長度不能超過2^16=65536;
  • 以太網(Ethernet)數據幀的長度,數據鏈路層的MTU(最大傳輸單元);
  • 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

數據有序性的差別

TCP

對於 TCP 來講,自己 TCP 有着超時重傳、錯誤重傳、還有等等一系列複雜的算法保證了 TCP 的數據是有序的,假設你發送了數據 一、二、3,則只要發送端和接收端保持鏈接時,接收端收到的數據始終都是 一、二、3。

UDP

而 UDP 協議則要奔放的多,不管 server 端不管緩衝池的大小有多大,接收 client 端發來的消息老是一個一個的接收。

而且因爲 UDP 自己的不可靠性以及無序性,若是 client 發送了 一、二、3 這三個數據報過來,server 端接收到的多是任意順序、任意個數三個數據報的排列組合。

可靠性的差別

其實你們都知道 TCP 自己是可靠的協議,而 UDP 是不可靠的協議。

TCP

TCP 內部的不少算法機制讓他保持鏈接的過程當中是很可靠的。好比:TCP 的超時重傳、錯誤重傳、TCP 的流量控制、阻塞控制、慢熱啓動算法、擁塞避免算法、快速恢復算法 等等。

因此 TCP 是一個內部原理複雜,可是使用起來比較簡單的這麼一個協議。

UDP

UDP 是一個面向非鏈接的協議,UDP 發送的每一個數據報帶有本身的 IP 地址和接收方的 IP 地址,它自己對這個數據報是否出錯,是否到達不關心,只要發出去了就行了。

因此來研究下,什麼狀況會致使 UDP 丟包:

  • 數據報分片重組丟失:在文章以前咱們就說過,UDP 的每一個數據報大小多少最合適,事實上 UDP 協議自己規定的大小是 64kb,可是在數據鏈路層有 MTU 的限制,大小大概在 5kb,因此當你發送一個很大的 UDP 包的時候,這個包會在 IP 層進行分片,而後重組。這個過程就有可能致使分片的包丟失。UDP 自己有 CRC 檢測機制,會拋棄掉丟失的 UDP 包;
  • UDP 緩衝區填滿:當 UDP 的緩衝區已經被填滿的時候,接收方尚未處理這部分的 UDP 數據報,這個時候再過來的數據報就沒有地方能夠存了,天然就都被丟棄了。

使用場景總結

在文章最後的一部分,聊聊 TCP、UDP 使用場景。

先來講 UDP 的吧,有不少人都會以爲 UDP 與 TCP 相比,在性能速度上是佔優點的。

由於 UDP 並不用保持一個持續的鏈接,也不須要對收發包進行確認。

但事實上通過這麼多年的發展 TCP 已經擁有足夠多的算法和優化,在網絡狀態不錯的狀況下,TCP 的總體性能是優於 UDP 的。

那在何時咱們非用 UDP 不可呢?

  • 對實時性要求高:好比實時會議,實時視頻這種狀況下,若是使用 TCP,當網絡很差發生重傳時,畫面確定會有延時,甚至越堆越多。若是使用 UDP 的話,即便偶爾丟了幾個包,可是也不會影響什麼,這種狀況下使用 UDP 比較好;
  • 多點通訊:TCP 須要保持一個長鏈接,那麼在涉及多點通信的時候,確定須要和多個通訊節點創建其雙向鏈接,而後有時在NAT環境下,兩個通訊節點創建其直接的 TCP 鏈接不是一個容易的事情,而 UDP 能夠無需保持鏈接,直接發就能夠了,因此成本會很低,並且穿透性好。這種狀況下使用 UDP 也是沒錯的。

以上咱們說了 UDP 的使用場景,在此以外的其餘狀況,使用 TCP 準沒錯。

畢竟有一句話嘛:

when in doubt,use TCP。
相關文章
相關標籤/搜索