【KCP】從零開始深入理解KCP原理(含TCP可靠機制原理), 及源碼解析。

目錄

KCP是什麼?

KCP商業案例

KCP的實現原理

停等式ARQ協議

確認機制

超時重傳

連續ARQ

(1) 回退n幀(go-back-n)ARQ

(2) 選擇重傳協議(selective repeat)(待補充)

滑動窗口協議

TCP應用的ARQ機制和其他機制(待更新)

接下來看一下KCP和TCP的對比:(待補充)

KCP源碼解析

KCP應用場景:(待補充)

參考文章:


查了不少KCP資料,可在很多文章中涉及到多種網絡底層術語和符號,對於網絡底層不怎麼了解的,看的簡直頭疼,還有對ARQ也缺乏描述,死磕了一段時間的網絡底層,才理解起來,因此在這篇文章裏會對各個涉及到的網絡術語進行解釋。主要針對對於網絡底層欠缺瞭解的同學。

大致說一下需要的前置知識,如果本文章沒有的話需要單獨瞭解一下。

  1. OSI模型,TCP/Ip模型(重點了解 傳輸層,網絡層,數據鏈路層,以及這些層的功能和傳輸單位)
  2. TCP實現原理(含可靠機制,本文章有講解),UDP實現原理
  3. ARQ(本文章有講解)

OK開始。

KCP是什麼?


官方簡介

官方地址:https://github.com/skywind3000/kcp

KCP是一個快速可靠協議,能以比 TCP浪費10%-20%的帶寬的代價,換取平均延遲降低 30%-40%,且最大延遲降低三倍的傳輸效果。純算法實現,並不負責底層協議(如UDP)的收發,需要使用者自己定義下層數據包的發送方式,以 callback的方式提供給 KCP。 連時鐘都需要外部傳遞進來,內部不會有任何一次系統調用。

術語解釋:

帶寬:是指在單位時間(一般指的是1秒鐘)內能傳輸的數據量。網絡和高速公路類似,帶寬越大,就類似高速公路的車道越多,其通行能力越強。

KCP到底是什麼?

嚴格意義上講KCP並不是一種網絡傳輸協議,它是爲UDP寫的可靠傳輸算法,它是把TCP的主要可靠傳輸機制移植到了UDP身上,讓UDP變的可靠了起來,所以想了解KCP的原理,就得先了解 TCP傳輸爲什麼可靠?UDP傳輸爲什麼不可靠?

KCP商業案例

  • 明日帝國:Game K17 的 《明日帝國》 (Google Play),使用 KCP 加速遊戲消息,讓全球玩家流暢聯網
  • 仙靈大作戰:4399 的 MOBA遊戲,使用 KCP 優化遊戲同步
  • CC:網易 CC 使用 kcp 加速視頻推流,有效提高流暢性
  • BOBO:網易 BOBO 使用 kcp 加速主播推流
  • 雲帆加速:使用 KCP 加速文件傳輸和視頻推流,優化了臺灣主播推流的流暢度
  • SpatialOS: 大型多人分佈式遊戲服務端引擎,BigWorld 的後繼者,使用 KCP 加速數據傳輸。

KCP的實現原理


KCP的出發點主要就是爲了讓UDP變的可靠,大家可以自己先思考一下,如何讓UDP變的可靠?
答案就是把TCP的可靠機制移植過來,可TCP的可靠機制是在傳輸層完成的,而UDP在傳輸層無法保證數據的可靠傳輸,只能通過應用層來實現了。實現的方式可以參照tcp可靠性傳輸的方式,只是實現不在傳輸層,實現轉移到了應用層。這就是KCP做法,也是其他UDP可靠算法的做法,在UDP身上套一個可靠機制算法,只不過使用上會有差異而已。
(提示:對於傳輸層,應用層,鏈路層不瞭解的同學,可以先了解一下OSI7層模型,Tcp/ip參考模型)
 附上圖:



So,瞭解了TCP可靠傳輸機制原理,那麼等於幾乎瞭解了KCP的實現原理,本文章重點會講 TCP的可靠機制,然後講KCP移植了哪些可靠機制,又與Tcp哪些地方不同。

TCP和UDP 可靠簡述:

  • TCP協議中使用了接收確認和重傳機制。使得每一個信息都能保證到達,所以是可靠的。
  • UDP是盡力傳送,沒有應答和重傳機制,UDP只是將信息發送出去,對方收不收到也不進行應答。所以UDP協議是不可靠的。

首先來講講TCP的可靠傳輸機制:

說到TCP可靠機制,先說一說自動重傳請求(Automatic Repeat-reQuest,ARQ,ARQ是屬於OSI模型中數據鏈路層的錯誤糾正協議之一,爲什麼說這個呢?因爲TCP傳輸層的主要可靠傳輸機制思想來自於ARQ。ARQ因現在鏈路的性能較好,目前在數據鏈路層很少採用。

總結成一句話就是TCP的可靠傳輸機制是在傳輸層完成的,而可靠機制原理應用的是ARQ的工作原理。搞懂了ARQ,就搞懂了真諦,當然TCP除了ARQ機制外,還有一些其他機制,本文章先講ARQ的可靠機制原理後再講TCP其他機制。

看協議之前先了解涉及到的符號以及術語

分組:分組是在互聯網中傳送數據的單元,把一個報文劃分爲幾個分組後再進行傳送,報文爲要發送的整塊數據。在發送報文之前,先把較長的報文劃分成爲一個個更小的等長數據段,在每一個數據段前面,加上一些由必要的控制信息組成的首部(header),就構成了一個分組(packet)。
幀:所謂數據幀(Data frame),就是數據鏈路層協議數據單元,它包括三部分:幀頭,數據部分,幀尾。其中,幀頭和幀尾包含一些必要的控制信息,比如同步信息、地址信息、差錯控制信息等;數據部分則包含網絡層傳下來的數據,比如IP數據包,等等。

TCP報文格式相關:
SYN:同步序列編號(Synchronize Sequence Numbers)。是TCP/IP建立連接時使用的握手信號。在客戶機和服務器之間建立正常的TCP網絡連接時,客戶機首先發出一個SYN消息,服務器使用SYN+ACK應答表示接收到了這個消息,最後客戶機再以ACK消息響應。這樣在客戶機和服務器之間才能建立起可靠的TCP連接。
FIN:Finish終結一個連接,是TCP/IP關閉連接時的揮手信號。
Seq:(Sequence Number) 是序列號,針對自身的,表示我發出去的數據分組,它的序列號。
Ack:(Acknowledge character)即是確認字符,在數據通信中,接收站發給發送站的一種傳輸類控制字符。表示發來的數據已確認接收無誤,回覆的ACK等於 = 發送方seq + 字節數 + 1,代表着已經收到發送方的s數據了, Ack是請求下一個seq數據。
PSH:發送(Push)。
RST重置(Reset) 
URG:緊急(Urgent)

Seq和Ack是保障TCK可靠傳輸的根本。

爲了方便理解,貼上圖,此圖是TCP連接和傳輸過程圖:

接下來看看ARQ的幾種典型協議:

  • 停等式ARQ(stop-and-wait)
  • 連續ARQ
    (1) 回退n幀(go-back-n)
    (2) 選擇重傳協議(selective repeat)
  • 滑動窗口協議(sliding window)

 
回退n幀(go-back-n)和 選擇重傳協議(selective repeat)是滑動窗口技術與請求重發技術的結合,又稱其爲連續ARQ協議。區別在於對於出錯的數據報文的處理機制不同。


停等式ARQ協議

主要講兩個功能

  1. 確認機制
  2. 超時重傳

確認機制

  1. 發送方 發送數據,然後暫停發送,等待接收方的ACK確認
  2. 收到 接收方回覆的ACK(確認號)
  3. 發送下一個數據

    如圖:

超時重傳

超時重傳:只要超過了一段時間還沒有收到確認,就認爲已發送的幀出錯或丟失了,因而重傳已發送過的幀。這就叫做超時重傳。
以下三種情況會進行超時重傳:

  1. 發送方 發送過程中出現差錯,導致接收方檢測出了差錯,丟棄了該數據幀。(發送方未收到確認應答,一直等待,直到超時)
  2. 發送方 發送過程中 丟失了(發送方未收到確認應答,一直等待,直到超時)
  3. 傳送延遲: 接收方接收成功後回覆了Ack確認,但是由於網絡原因延遲了, 也就是Ack確認在發送方超時後纔到達。而發送方超時時已經重傳了一次, 此時接收方要做的事情:丟棄重複分組,重新發送確認. 發送方如果收到兩個或者多個確認,除了第一個確認,丟棄其他確認.

    如圖:

停止等待協議的優點是簡單,但缺點是信道的利用率太低,一次發送一條消息,使得信道的大部分時間內都是空閒的。

如下圖:

連續ARQ

由於停止等待ARQ協議信道利用率太低,所以需要使用連續ARQ協議來進行改善。這個協議會連續發送一組數據包,然後再等待這些數據包的ACK。
發送方採用流水線傳輸。流水線傳輸就是發送方可以連續發送多個分組,不必每發完一個分組就停下來等待對方確認。

如下圖所示


 

(1) 回退n幀(go-back-n)ARQ

發送方:發送方根據窗口大小不用等待接收方的應答,持續的發送多個幀,假如發現已發送的幀中有錯誤發生,那麼從那個發生錯誤的幀開始及其之後所有的幀全部再重新發送,這就叫回退n幀

接收方:接收方一般都是採用累積確認的方式。也就是說接收方不必對收到的分組逐個發送確認。而是在收到幾個分組後,對按序到達的最後一個分組發送確認。如果收到了這個分組確認信息,則表示到這個分組爲止的所有分組都已經正確接收到了。

如圖:

在上圖中左側方發送的序列號爲0,1的數據,右測方已正確收到,並且回覆Ack確認成功,但右側方在收到序列號爲2的數據時,發現錯誤並丟棄,左側方等到超時後回退n幀到序列號爲2的數據,然後全部重傳一遍。

(2) 選擇重傳協議(selective repeat)(待補充)

它通過讓發送方僅重傳那些它懷疑在接收方出錯(即丟失或受損)的分組而避免了不必要的重傳。選擇重傳協議只重傳真正丟失的分組.

滑動窗口協議

TCP採用可變滑動窗口來實現流量控制。TCP連接的兩端交互作用,互相提供數據流的相關信息,包括報文段序列號、ACK號和窗口大小(即接收端的可用空間)。發送端根據這些信息動態調節窗口大小來控制發送,以達到流量控制的目的。每個TCP頭部的窗口大小字段表明接收端可用緩存空間的大小。

每個TCP連接的兩端都維護一組窗口:發送窗口結構(send window structure)和接收窗口結構(receive window structure)。TCP以字節爲單位維護其窗口結構。TCP頭部中的窗口大小字段相對ACK號有一個字節的偏移量。發送端計算其可用窗口,即它可以立即發送的數據量。可用窗口(允許發送但還未發送)計算值爲提供窗口(即由接收端通告的窗口)大小減去在傳(已發送但未得到確認)的數據量。圖中P1、P2、P3分別記錄了窗口的左邊界、下次發送的序列號、右邊界。

如下圖所示,

隨着發送端接收到返回的數據ACK,滑動窗口也隨之右移。發送端根據接收端返回的ACK可以得到兩個重要的信息:一是接收端期望收到的下一個字節序號;二是當前的窗口大小(再結合發送端已有的其他信息可以得出還能發送多少字節數據)。如下圖所示

如上文所述,窗口大小是動態變化的,如下圖所示,每次發送數據都會附帶窗口大小。

 

 

TCP應用的ARQ機制和其他機制(待更新)

 

接下來看一下KCP和TCP的對比:(待補充)

其他對比待更新

來自官方對比

  • 選擇性重傳 vs 全部重傳:
    TCP丟包時會全部重傳從丟的那個包開始以後的數據,KCP是選擇性重傳,只重傳真正丟失的數據包。(也就是TCP採用的是回退n幀,而KCP採用的選擇性重傳
  • 快速重傳:
    發送端發送了1,2,3,4,5幾個包,然後收到遠端的ACK: 1, 3, 4, 5,當收到ACK3時,KCP知道2被跳過1次,收到ACK4時,知道2被跳過了2次,此時可以認爲2號丟失,不用等超時,直接重傳2號包,大大改善了丟包時的傳輸速度。

  • 延遲ACK vs 非延遲ACK
    TCP爲了充分利用帶寬,延遲發送ACK(NODELAY都沒用),這樣超時計算會算出較大 RTT時間,延長了丟包時的判斷過程。KCP的ACK是否延遲發送可以調節。

  • UNA vs ACK+UNA
    ARQ模型響應有兩種,UNA(此編號前所有包已收到,如TCP)和ACK(該編號包已收到),光用UNA將導致全部重傳,光用ACK則丟失成本太高,以往協議都是二選其一,而 KCP協議中,除去單獨的 ACK包外,所有包都有UNA信息。

  • 非退讓流控
    KCP正常模式同TCP一樣使用公平退讓法則,即發送窗口大小由:發送緩存大小、接收端剩餘接收緩存大小、丟包退讓及慢啓動這四要素決定。但傳送及時性要求很高的小數據時,可選擇通過配置跳過後兩步,僅用前兩項來控制發送頻率。以犧牲部分公平性及帶寬利用率之代價,換取了開着BT都能流暢傳輸的效果。

 

KCP源碼解析

UDP收到的包,不斷通過kcp_input餵給KCPKCP會對這部分數據(KCP協議數據)進行解包,重新封裝成應用層用戶數據,應用層通過kcp_recv獲取。應用層通過kcp_send發送數據,KCP會把用戶數據拆分kcp數據包,通過kcp_outputUDPsend的方式發送

源碼字段中名詞說明:

用戶數據:應用層發送的數據,如一張圖片2Kb的數據
MTU最大傳輸單元。即每次發送的最大數據
RTORetransmission TimeOut重傳超時時間。
cwndcongestion window擁塞窗口,表示發送方可發送多少個KCP數據包。與接收方窗口有關,與網絡狀況(擁塞控制)有關,與發送窗口大小有關。
Rwndreceiver window,接收方窗口大小,表示接收方還可接收多少個KCP數據包
snd_queue:待發送KCP數據包隊列
snd_nxt:下一個即將發送的kcp數據包序列號
snd_una:下一個待確認的序列號

 

KCP應用場景:(待補充)

適用場景是客戶端與服務端交互很頻繁的遊戲。

  1. 幀同步
  2. 狀態同步


參考文章:

  1. https://blog.csdn.net/guoweimelon/article/details/50879588 TCP連續ARQ協議和滑動窗口協議
  2. https://www.jianshu.com/p/6a4ec6095f2c TCP 可靠性保證
  3. https://www.jianshu.com/p/e16ae45239ca TCP的可靠性傳輸
  4. https://www.cnblogs.com/blythe/articles/7348812.html  TCP連續ARQ協議和滑動窗口協議
  5. https://wenku.baidu.com/view/75395bdbcc175527062208a1.html 數據鏈路層(ARQ,PPP)
  6. https://blog.csdn.net/btb5e6nsu1g511eg5xeg/article/details/80165735 分分鐘讀懂tcp/ip通信協議原理(含視頻)
  7. https://blog.csdn.net/weixin_42867972/article/details/82054814 TCP/IP 模型 與 OSI 七層模型的對應關係
  8. https://blog.csdn.net/qq_37653144/article/details/82765098 TCP滑動窗口與流量控制
  9. 其他
     

 

發佈了9 篇原創文章 · 獲贊 24 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章