TCP/UDP對比總結

shell_nut 發表於2019-08-13

  在計算機網路中,有三種體系結構劃分方式,第一種是OSI七層協議體系結構,由上到下分別是:應用層,表示層,會話層,運輸層,網路層,資料鏈路層,物理層;第二種是TCP/IP四層協議,由上到下分別是:應用層,運輸層,網際層,網路介面層。第一種劃分方式複雜又不實用,第二種劃分方式最下面“網路介面層”對計算機網路來說,和一般的通訊鏈路沒有多大的區別,所以最後折中為我們常用的五層協議:應用層,運輸層,網路層,資料鏈路層,物理層。
  運輸層向它上面的應用層提供服務,它屬於面向通訊部分的最高層,同時也是使用者功能的最底層。兩個主機通過核心網路進行端到端通訊時,只有主機部分有運輸層,核心網路部分的路由在轉發分組時只用到下面三層。
  TCP/UDP作為傳輸層協議,各自都有著非常廣泛的應用場景,下面先對這兩種協議做一個簡單對比,然後分別介紹下這兩種協議。本文僅從原理上介紹兩種協議,暫並不涉及程式設計。

1 TCP-UDP對比

  相同點:
  TCP和UDP都是網路層之上的,傳輸層協議,都能都能保護網路層的傳輸,雙方的通訊都需要開放埠,TCP和UDP中都存在複用分用技術。
  不同點:
  一提到TCP-UDP的區別,大家最容易想到的便是TCP是可靠傳輸的,UDP是不可靠傳輸的,下面就簡單羅列一下:

選項 TCP UDP
可靠性 全雙工可靠傳輸無差錯,不丟失,不重複,且按序到達 盡最大努力交付
建立連線 需要建立連線 無需建立連線
資料傳送模式 面向位元組流 面向報文
傳輸方式 點對點(不支援廣播和多播) 一對一,一對多,多對一,多對多
首部開銷 20位元組 8位元組
擁塞機制
流量控制
系統資源佔用 對系統資源要求較多 對系統資源要求較少
實時性 相對UDP較低 較高,適用於對高速傳輸和實時性要求較高的通訊或廣播通訊
確認重傳機制 TCP提供超時重發,丟棄重複資料,檢驗資料, 無重傳,只是把應用程式傳給IP層的資料包傳送出去,但是並不能保證它們能到達目的地

  對於上表中所述“資料傳送模式”做一下簡單補充:
  對TCP:TCP不關心應用程式一次性把多長的資料包文傳送到TCP快取中,而是根據對方給出的視窗值和網路擁塞程度決定報文段應該包含多少位元組.
  對UDP:一次交付一個完整的報文,報文長度由應用程式給出。

2 UDP介紹

  對於UDP的介紹以及提點在第一節比較中已做了詳細描述,這裡提一點:雖說UDP的不可靠傳輸特性在很多應用場景中大展身手,但是也要儘可能的提高UDP傳輸的可靠性。如何提高UDP的可靠性呢?應用程式可以在不影響應用的實時性的前提下,增加一個提高可靠性的措施,如採用前向糾錯或重傳已丟失的報文。

3 TCP介紹

  對於TCP的介紹,主要圍繞一個主題,為什麼說TCP是可靠傳輸,下面會分別從可靠傳輸的原理和實現,面向連線,流量控制,擁塞控制,幾個方面進行介紹。

  對TCP的介紹有一個前提:只介紹單項傳輸,有A傳輸資料給B

3.1 可靠傳輸的原理和實現

3.1.1 可靠傳輸原理

  可靠傳輸的原理主要依賴於兩個協議:停止等待協議和連續ARQ協議,下面分別介紹之:

1 停止等待協議

  當A向B傳輸資料時,A收到B的確認才傳送下一個分組。如果收不到B的確認,A會重傳上一個未收到確認的報文。具體確認重傳機制如下:當A向B傳送資料後,A會開啟一個超時計時器,計時時間內收到B的確認,傳送下一個報文,若計時器超時,還沒有收到B發來的確認,A重傳上一個未收到確認的報文。
  在確認重傳機制中存在一個“確認丟失和確認遲到”的現象。
  “確認丟失”表示B發給A的確認報文在傳輸過程中丟失,A沒有收到,當A的超時計數器超時後,A會重傳報文,B接收到該重傳報文後,丟棄該報文重新傳送確認
  “確認遲到”表示B發給A的確認報文卡在了傳輸過程中的某一個環節,A沒有收到,當A的超時計數器超時後,A會重傳報文,B接收到該重傳報文後,丟棄該報文並重新傳送確認,A接收到重複發來的確認報文後,丟棄該報文不做任何處理

2 連續ARQ協議

  在A傳送報文時使用一個合適大小的視窗(也即後面提到的滑動視窗),A傳送報文段從該視窗中依次傳送,A每接收到一個確認,該視窗就向後移動一個報文段。此時B一般不會收到每個報文段都回復一個確認,而是採用累積確認的方式,即在B收到幾個分組後,對按順序到達的最後一個分組傳送確認,表示到這個分組為止的所有分組都已經收到了。

3.1.2 可靠傳輸實現

  在面向連線的基礎上,主要是通過以位元組為單位的滑動視窗超時重傳選擇確認這三種方式,並輔以流量控制和擁塞控制這兩種機制,來實現TCP的可靠傳輸。

3.2 TCP面向連線管理

3.2.1 建立連線

  如上圖,是TCP建立連線的示意圖,下面分佈說明之:
  1 考試客戶端A和伺服器端B都處於CLOSE狀態;並且A是主動開啟連線,B是被動開啟連線;
  2 B的伺服器程式建立傳輸控制塊TCB,進入LISTEN(收聽)狀態,等待客戶端傳送請求。TCB用來儲存每一個連線中的一些重要資訊,如TCP連線表,到傳送和接收快取的指標,到重傳佇列的指標,當前的傳送和接受序號等;
  3 客戶端A也建立TCB,向B發出連線請求報文段,其中首部中同部位SYN = 1,選擇一個初始序列號seq = x,進入SYN-SEND(同步已傳送)狀態。SYN報文段不攜帶資料,佔用一個序列號;
  4 B收到請求報文段後,如同意連線,向A傳送確認,其中SYNACK都置為1,確認號ack = x+1,選擇一個初始序列號seq = y,進入SYN-RCVD(同步收到)狀態,該報文段不攜帶資料,佔用一個序列號;
  5 A收到B的確認後,再給B發確認,其中ACK = 1,ack = y+1,seq = x+1。A進入ESTABLISHED(已建立連線狀態)。可帶資料可不帶,若不攜帶資料則不消耗序列號,下次傳送資料序列號依舊是seq = x+1
  6 B收到A的確認後,B進入ESTABLISHED(已建立連線狀態)。

3.2.2 釋放連線

  如上圖,是TCP釋放連線的示意圖,下面分佈說明之:
  1 A,B都處於 ESTABLISHED狀態,假設A的程式先向B發出釋放連線報文段,FIN = 1,seq等於上一次傳送資料最後一個位元組的序號加1;此時A進入FIN-WAIT-1(終止等待1)狀態;
  2 B收到連線釋放報文段後,發出確認,ACK置為1,ack = u+1,seq等於上一次傳送資料最後一個位元組的序號加1;此時B進入CLOSE-WAIT(關閉等待)狀態;此時TCP伺服器程式通知高層應用程式A到B的連線釋放了,此時,A沒有資料傳送給B,但是B可以傳送資料給A,A要接受;屬於半關閉狀態
  3 A收到來自B的確認後,進入FIN-WAIT-2(終止等待2)狀態,等待B傳送釋放連線報文段;在此期間,A有可能還會收到B發過來的資料;
  4 當B沒有資料傳送到A時,向A傳送連線釋放報文段,FIN = 1,假定B的req = w(假設在半關閉狀態B又向A傳送資料),確認號重複上次的確認號ack = u+1;此時B處於LAST-ACK(最後確認)狀態;
  5 A收到B的連線釋放報文段時,向B發出確認,ACK置為1,自己的序列號req = u+1(根據TCP規定,前面傳送的FIN報文段需要消耗一個報文段);此時A進入TIME-WAIT(時間等待)狀態;此時,連線還沒有釋放,A等到2倍的最長報文段壽命MSL(4分鐘)後,才能釋放連線,A進入CLOSE狀態,隨時準備下一個連線;
  6 B收到A的確認後,進入CLOSE狀態,隨時準備下一個連線。

3.3 流量控制

  流量控制往往指點對點通訊量的控制,是端到端的問題。流量控制所要做的就是:抑制傳送端的傳送速率,以便接收端來得及接收。
  主要是由接收方通過傳送給傳送方的控制視窗的大小,開控制傳送方的傳送速率。

3.4 擁塞控制

  擁塞控制是一個全域性性的過程,涉及到所有的主機,所有的路由器等,主要是防止過多的資料注入到網路中,使網路能夠承受現有的網路負荷。總之一句話,要做到可用的資源大於對網路資源的總需求,這樣就能防止網路擁塞。
  防止網路擁塞有兩種方法,“慢開始和擁塞避免”和“快重傳和快恢復”,下面分別介紹之:

1 慢開始和擁塞避免

  前提:TCP中是以位元組作為視窗的單位,這裡為了描述方便,使用報文段的個數作為視窗的大小。
  1 傳送方開始傳送資料時,擁塞視窗cwnd設定為一個最大報文段MSS的大小;
  2 傳送方收到確認後,傳送方把擁塞視窗cwnd設定為2,這樣傳送方可以傳送第二,第三個報文段;
  3 傳送方每收到一個報文段的確認後,cwnd的大小加1,由於接收方採用累積確認的方式,當傳送方接收到報文段3的確認時,傳送方把擁塞視窗cwnd設定為4;
  4 這樣,每經過一個輪次,cwnd就加倍。所謂輪次。是指把擁塞視窗cwnd所允許的所有報文段都傳送出去,並收到對已傳送的最後一個位元組的確認,這個輪次稱為一次往返時間RTT;
  5 擁塞視窗cwnd以此指數規律增長,但並不能一直增長下去,會產生擁塞。此時設定一個慢開始門限ssthresh,當cwnd大於ssthresh時,使用擁塞避免演算法;
以上是慢開始演算法,以下是擁塞避免演算法
  6 當cwnd大於ssthresh時,ssthresh減為當前cwnd的一半大小(乘法減小),cwnd從1開始增加(加法增大),繼續使用慢開始演算法,依次迴圈使用兩種演算法。

總結:
cwnd > ssthresh時,使用慢開始演算法
cwnd < ssthresh時,使用擁塞避免演算法
cwnd = ssthresh時,兩種演算法都能使用

2 快重傳和快恢復

  1 假設接收方已經接收到第二個報文段,緊接著收到第四個報文段,沒有收到第三個報文段,由於是TCP協議累積確認時針對按序到達的報文段,此時不能對第四個報文段確認,接收方只能傳送第二個報文段的確認;
  2 由於接受方的超時計數器還沒有超時,傳送方接著傳送第五個報文段和第六個報文段;
  3 接收方收到第五個報文段和第六個報文段時,還是沒有收到第三個報文段,依次在收到第五個報文段和第六個報文段後向傳送方回覆第二個報文段的確認;
  4 當傳送方連續接收到三個確認報文後,就會使用快恢復演算法
以上是快重傳演算法,以下是快恢復演算法
  5 當傳送方連續接收到三個確認報文後,執行“乘法減小演算法”,把慢開始門限ssthresh減半,cwnd設定為慢開始門限ssthresh減半後的數值,然後使用擁塞避免演算法。