博客 / 詳情

返回

KCP技術原理

KCP技術原理

KCP是什麼

開源地址: https://github.com/skywind3000/kcp/tree/master

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

這裏翻譯一下,供參考

  1. KCP是一個ARQ協議:Automatic Repeat Query/Automatic repeat request,自動消息重發機制。
  2. 可靠協議,解決了丟包、亂序等問題。
  3. 可實現可靠UDP傳輸。不負責底層協議的收發,但是可以應用在幾乎任何底層協議上,比如UDP。
  4. 比TCP快速,延遲低。

實現原理

網絡模塊是非常重要基礎模塊,瞭解實現原理和實現細節非常重要。這關係到後續出現問題能否解決,根據項目情況進一步定製,甚至技術選型是否能通過等重要問題。

KCP實現了一整套與TCP類似/功能對應的機制,它們有:

  • 超時重傳
  • 快速重傳
  • 滑動窗口
  • 流量控制
  • 擁塞控制

那我們為什麼不直接用TCP呢?或者説它為什麼比TCP快?

用作者的話説:TCP是為流量設計的(每秒內可以傳輸多少KB的數據),講究的是充分利用帶寬。而KCP是為流速設計的(單個數據包從一端發送到一端需要多少時間),以10%-20%帶寬浪費的代價換取了比 TCP快30%-40%的傳輸速度。

因為TCP在傳輸層,用户程序不能進行更多的定製,基於UDP的KCP就可以通過調節與TCP類似的機制中的一些設定,實現了下面的技術特性,達到了提高流速的效果。

  • RTO翻倍vs不翻倍:TCP超時計算是RTOx2,這樣連續丟三次包就變成RTOx8了,十分恐怖,而KCP啓動快速模式後不x2,只是x1.5(實驗證明1.5這個值相對比較好),提高了傳輸速度。
  • 選擇性重傳 vs 全部重傳:TCP丟包時會全部重傳從丟的那個包開始以後的數據,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又會導致 ACK丟失成本太高。KCP有單獨ACK,且數據包和ACK包都帶UNA信息,有效降低ACK丟失成本。
  • 非退讓流控:KCP正常模式同TCP一樣使用公平退讓法則,即發送窗口大小由:發送緩存大小、接收端剩餘接收緩存大小、丟包退讓及慢啓動這四要素決定。但傳送及時性要求很高的小數據時,可選擇通過配置跳過後兩步,僅用前兩項來控制發送頻率。以犧牲部分公平性及帶寬利用率之代價,換取了開着BT都能流暢傳輸的效果。

使用原理

以一個消息的收發為例:

  1. 使用socket接口搭建udp底層通信,例如C#的Socket API。
  2. 發送數據前,調用kcp的send接口,發送到kcp,進行數據包拆分、封裝。
  3. 設置kcp的output回調接口,數據包處理完成後,自動回調output接口。在這裏通過socket發送到服務器
  4. 服務器部分運行流程與客户端相同,這裏略過。消息處理完成後,服務器發包到客户端。
  5. 客户端的socket接口收到數據,調用kcp的input接口,kcp對數據包進行合併、解包。再通過回調接口,把真實的數據包返回給客户端進行邏輯處理。

圖示

接下來,結合大量現成的TCP資料的機制原理,一一講解KCP這些技術特性。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.