英語の README
KCP は、TCP よりも 10% ~ 20% 多い帯域幅を犠牲にして、平均遅延を 30% ~ 40% 削減し、最大遅延を 3 倍削減できる高速で信頼性の高いプロトコルです。純粋なアルゴリズムの実装は、基礎となるプロトコル (UDP など) の送受信を担当しません。ユーザーは、下位層のデータ パケットの送信メソッドを定義し、それをコールバックの形式で KCP に提供する必要があります。 クロックさえも外部から渡す必要があり、内部ではシステムコールは行われません。
プロトコル全体には、ikcp.h と ikcp.c の 2 つのソース ファイルしかなく、ユーザー独自のプロトコル スタックに簡単に統合できます。 P2P または UDP ベースのプロトコルは実装しているものの、完全で信頼性の高い ARQ プロトコルの実装が不足している場合は、これら 2 つのファイルを既存のプロジェクトにコピーし、数行のコードを記述するだけで使用できます。
TCP はトラフィック (1 秒あたり何 KB のデータを送信できるか) を考慮して設計されており、帯域幅を最大限に活用することに重点が置かれています。 KCP は、フロー レート (単一のデータ パケットが一方の端からもう一方の端に送信されるのにかかる時間) を考慮して設計されており、帯域幅の無駄の 10% ~ 20% を TCP よりも 30% ~ 40% 高速に変換します。 。 TCP チャネルは、流速は遅いが 1 秒あたりの流量が大きい大きな運河ですが、KCP チャネルは流れが速い小さな急流です。 KCP には、通常モードと高速モードの 2 つのタイプがあり、次の戦略によって流量を増加させます。
TCP タイムアウトの計算は RTOx2 で、連続して 3 つのパケットが失われると RTOx8 になります。ただし、KCP が高速モードを開始すると、2 倍にはならず、1.5 倍にしかならないことが実験で証明されています。 1.5 の値は比較的良好です)。これにより、伝送速度が向上します。
TCP はパケットを失うと、失われたパケットから始まるすべてのデータを再送信し、実際に失われたデータ パケットのみを再送信します。
送信者はいくつかのパケット 1、2、3、4、5 を送信し、リモート エンドから ACK 1、3、4、5 を受信しました。ACK3 を受信すると、KCP は 2 が 1 回スキップされたことを認識し、ACK4 を受信しました。このとき、パケット番号 2 が 2 回スキップされたことがわかり、タイムアウトを待たずにパケット番号 2 を直接再送することができるため、パケット損失時の伝送速度が大幅に向上します。
TCP は帯域を最大限に活用するために ACK の送信を遅らせます (NODELAY は役に立ちません)。このようにタイムアウト計算ではより大きな RTT 時間が計算され、パケット損失が発生した場合の判定処理が長くなります。 KCP の ACK を遅延して送信するかどうかを調整できます。
ARQ モデル応答には、UNA (TCP など、この番号よりも前のすべてのパケットが受信されている) と ACK (この番号を持つパケットが受信されている) の 2 つのタイプがあります。UNA を単独で使用するとすべての再送信が発生し、ACK だけを使用すると再送信が発生します。以前は、プロトコルは 2 つのうちの 1 つを選択することがすべてでしたが、KCP プロトコルでは、個々の ACK パケットを除いて、すべてのパケットに UNA 情報が含まれます。
KCP ノーマル モードでは、TCP と同じ公平な譲歩ルールが使用されます。つまり、送信ウィンドウ サイズは、送信バッファ サイズ、受信側の残りの受信バッファ サイズ、パケット損失の譲歩、およびスロー スタートの 4 つの要素によって決まります。ただし、適時性が求められる小さなデータを送信する場合は、構成の最後の 2 つの手順をスキップし、最初の 2 つの項目のみを使用して送信頻度を制御することを選択できます。公平性と帯域幅の使用率をある程度犠牲にしても、BT がオンになっている場合でも、スムーズな送信の効果を得ることができます。
vcpkg ライブラリ マネージャーを使用して、kcp をダウンロードしてインストールできます。
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install kcp
vcpkg の kcp ライブラリは、Microsoft チームのメンバーとコミュニティの貢献者によって最新の状態に保たれています。バージョンが古い場合は、vcpkg リポジトリで問題を作成するか PR を上げてください。
KCP オブジェクトを作成します。
// 初始化 kcp对象,conv为一个表示会话编号的整数,和tcp的 conv一样,通信双
// 方需保证 conv相同,相互的数据包才能够被认可,user是一个给回调函数的指针
ikcpcb *kcp = ikcp_create(conv, user);
コールバック関数を設定します。
// KCP的下层协议输出函数,KCP需要发送数据时会调用它
// buf/len 表示缓存和长度
// user指针为 kcp对象创建时传入的值,用于区别多个 KCP对象
int udp_output ( const char *buf, int len, ikcpcb *kcp, void *user)
{
....
}
// 设置回调函数
kcp->output = udp_output;
ループ内で update を呼び出します。
// 以一定频率调用 ikcp_update来更新 kcp状态,并且传入当前时钟(毫秒单位)
// 如 10ms调用一次,或用 ikcp_check确定下次调用 update的时间不必每次调用
ikcp_update (kcp, millisec);
下位層パケットを入力します。
// 收到一个下层数据包(比如UDP包)时需要调用:
ikcp_input (kcp, received_udp_packet, received_udp_size);
下位層プロトコルの出力/入力を処理した後、KCP プロトコルは正常に動作し、ikcp_send を使用してデータをリモート エンドに送信できます。もう一方の端は、ikcp_recv(kcp, ptr, size) を使用してデータを受信します。
プロトコルのデフォルト モードは標準 ARQ であり、構成を通じてさまざまなアクセラレーション スイッチをオンにする必要があります。
作業モード:
int ikcp_nodelay (ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
最大ウィンドウ:
int ikcp_wndsize (ikcpcb *kcp, int sndwnd, int rcvwnd);
この呼び出しは、プロトコルの最大送信ウィンドウ サイズと最大受信ウィンドウ サイズを設定します。デフォルトは 32 です。これは、TCP の SND_BUF および RCV_BUF として理解できますが、単位は異なります。SND/RCV_BUF の単位はバイトです。パケット。
最大伝送単位:
純粋なアルゴリズム プロトコルは MTU を検出しません。デフォルトの mtu は 1400 バイトです。ikcp_setmtu を使用してこの値を設定できます。この値は、データ パケットを結合およびフラグメント化するときの最大送信単位に影響します。
最小 RTO:
TCP であっても KCP であっても、RTO を計算する際には最小 RTO 制限があります。たとえ計算された RTO が 40 ミリ秒であっても、デフォルトの RTO は 100 ミリ秒であるため、プロトコルは高速モードでは 100 ミリ秒以降のパケット損失しか検出できません。この値は手動で変更できます。
kcp->rx_minrto = 10 ;
プロトコルの使用方法と設定は非常に簡単で、ほとんどの場合、上記の内容を読んだだけで使用できます。 KCP のメモリ アロケータの変更など、さらにきめ細かい制御が必要な場合、または大規模な KCP 接続 (3,500 以上など) をより効率的にスケジュールする必要がある場合、または TCP とより適切に統合する方法が必要な場合は、次のことができます。続きを読む:
関連記事: 「原神」も KCP を利用してゲームニュースをスピードアップ
KCP は、数億人のユーザーが参加する複数のプロジェクトで正常に実行され、より応答性が高くスムーズなネットワーク エクスペリエンスをユーザーに提供しています。
もっと多くの事例を教えてください
ネットワークがまったくスタックしない場合、KCP/TCP は同様に動作しますが、ネットワーク自体は信頼性が低く、パケット損失やジッターは避けられません (そうでない場合、なぜ信頼できるさまざまなプロトコルが必要になるのでしょうか)。イントラネットなどのほぼ理想的な環境で直接比較すると、どれもほぼ同じですが、公衆ネットワーク上、3G/4G ネットワーク上、またはイントラネットのパケット損失シミュレーションを使用すると、違いは明らかです。パブリック ネットワークでは、ピーク時に平均 10% 近くのパケット損失が発生します。WiFi/3g/4g ではさらに悪化し、伝送遅延が発生します。
asio-kcp の著者である zhangyuan に感謝します。KCP、enet、および udt の水平評価に感謝します。結論は次のとおりです。
詳細については、水平比較と評価データを参照してください。選択を迷っている人にさらなる指針を提供します。
大規模マルチプレイヤー ゲーム サーバー エンジン SpatialOS は、KCP プロトコルを統合した後、TCP/RakNet と同じ評価を行いました。
サーバー側で 60 Hz のリフレッシュ レートで同時に 50 文字を維持した場合の応答時間を比較しました。詳細な比較レポートを参照してください。
近年、オンラインゲームや各種ソーシャルネットワークは飛躍的に成長しており、双方向性と複雑性が急速に高まっており、非常に短時間に同時にデータを配信する必要があります。ユーザーにとって、伝送技術は当然、将来の開発を制限する重要な要素となり、raknet/enet など、オープンソースの世界でよく知られているさまざまな伝送プロトコルが登場します。たとえば、リリースが行われると、プロトコル スタック全体がまとめてリリースされます。この形式は、あなたを使用するかどうかを選択することしかできませんが、設計するのはあなたです。プロトコルスタックのセットがどれほど優れていても、さまざまな角度からさまざまなニーズに応えることは非常に困難です。
したがって、KCP の方法は、プロジェクトのニーズに応じて誰もが柔軟に調整して組み立てることができるように、プロトコル スタックを「逆アセンブル」することです。FEC を行うために以下のリード ソロモンの消去コードのレイヤーを追加したり、上記の RC4/Salsa20 のようなレイヤーを追加したりすることができます。ストリーム暗号化の場合、ハンドシェイク時に非対称キー交換が設計され、複数のパスを同時に検出して送信に最適なパスを選択する動的ルーティング システムが基礎となる UDP トランスポート層に構築されます。これらの異なる「プロトコルユニット」を必要に応じてビルディングブロックのように自由に組み合わせることで「シンプルさ」と「着脱性」を確保し、変化するビジネスニーズに柔軟に対応します。
将来の伝送ソリューションは、使用シナリオに応じて徹底的にカスタマイズする必要があるため、独自のプロトコル スタックへの統合を容易にするために、自由に組み合わせることができる「プロトコル ユニット」を全員に提供します。
詳細については、成功事例をご覧ください。
著者: リン・ウェイ (skywind3000)
個人ブログと Twitter で私をフォローしてください。
長年の開発経験の中で、私は常にプログラムのボトルネック問題を研究して解決することが好きでした。初期の頃は、「VGA プログラミング」に従ってゲーム グラフィックスを作成し、Michael Abrash の「グラフィックス プログラム」を読みました。開発者ガイド」を参照して、ソフト レンダリングを実行します。私は、CPU を圧迫してより高速に実行できるコードで遊ぶのが好きです。この仕事に参加した後、私の興味はサーバー側とネットワーク関連のテクノロジに移りました。
いくつかの伝統的なゲームを作成した後、2007 年に私は高速アクション ゲームの同期問題を研究し始めました。この間、私は中国で最も早く同期問題を研究した人の 1 人でした。同期をどう解決するにしても、ネットワーク伝送に関して何かをする必要があります。ゲームを離れてインターネットに切り替えた後、多くの分野でこのニーズがあることに気づき、ネットワーク伝送の分野に時間を費やすようになりました。 、UDP に基づいていくつかの保守的で信頼性の高いプロトコルを実装しようとしており、BSD Lite 4.4 のコードを模倣して TCP のようなものを実装しています。プロトコルに興味を持ち、P2P およびダイナミック ルーティング ネットワークに関連するいくつかのおもちゃを実装しました。 KCP プロトコルは 2011 年に誕生しました。基本的には、送信に関して独自に作成されたいくつかのおもちゃの 1 つです。
Kcptun の作者である xtaci は私の大学の同級生で、私たちは二人とも通信を専攻しており、送信を最適化する方法をよく一緒に研究しています。
Alipay を使用して上記の QR コードをスキャンして、このプロジェクトに寄付してください。寄付は、KCP プロトコルの継続的な最適化とドキュメントの改善に使用されます。
感謝の意:Mingming、Xingzi、Jin、Fan、Yanzhao、Binquan、Xiaodan、Yu Zheng、Hu、Shenggan、Xu Wei、Wang Chuan、Zhao Gangqiang、Hu Zhifeng、Wan Xinchao、He Xinchao、Liu Yang、Hou Xianhui、Wu Peiyi 、ホア・ビン、ルタオ、フー・ジェン。 。 。 (先ほどのリストを記録していなくて本当に申し訳ありません) クラスメートの皆様からの寄付やご支援をお待ちしております。
ようこそ注目してください
KCP 通信グループ: 364933586 (QQ グループ番号)、KCP 統合、チューニング、ネットワーク伝送および関連する技術的な議論
Gitter グループ: https://gitter.im/skywind3000/KCP
ブログ: http://www.skywind.me
このプロジェクトは、貢献してくださったすべての人々のおかげで存在します。