README en anglais
KCP est un protocole rapide et fiable qui peut réduire le délai moyen de 30 à 40 % et réduire le délai maximum de trois fois au prix de 10 à 20 % de bande passante en plus que TCP. La mise en œuvre d'algorithmes purs n'est pas responsable de l'envoi et de la réception des protocoles sous-jacents (tels que UDP). Les utilisateurs doivent définir la méthode d'envoi des paquets de données de couche inférieure et la fournir à KCP sous forme de rappel. Même l'horloge doit être transmise en externe et il n'y aura aucun appel système en interne.
L'ensemble du protocole ne comporte que deux fichiers sources, ikcp.h et ikcp.c, qui peuvent être facilement intégrés dans la propre pile de protocoles de l'utilisateur. Peut-être avez-vous implémenté un protocole P2P ou basé sur UDP mais il vous manque une implémentation complète et fiable du protocole ARQ. Copiez simplement ces deux fichiers dans le projet existant, écrivez quelques lignes de code et vous pourrez l'utiliser.
TCP est conçu pour le trafic (combien de Ko de données peuvent être transmis par seconde) et l'accent est mis sur l'utilisation complète de la bande passante. KCP est conçu pour le débit (le temps nécessaire pour qu'un seul paquet de données soit envoyé d'un bout à l'autre). Il échange 10 à 20 % de perte de bande passante contre une vitesse de transmission 30 à 40 % plus rapide que TCP. . Le canal TCP est un grand canal avec un débit lent mais un débit par seconde important, tandis que le canal KCP est un petit canal rapide à débit rapide. KCP a deux types : le mode normal et le mode rapide. Le résultat de l'augmentation du débit est obtenu grâce aux stratégies suivantes :
Le calcul du délai d'attente TCP est RTOx2. Si vous perdez trois paquets d'affilée, cela deviendra RTOx8, ce qui est très effrayant. Cependant, une fois que KCP a démarré le mode rapide, ce n'est pas x2, mais seulement x1,5 (des expériences l'ont prouvé). la valeur de 1,5 est relativement bonne), ce qui améliore la vitesse de transmission.
Lorsque TCP perd un paquet, il retransmet toutes les données à partir du paquet perdu. KCP retransmet sélectivement et ne retransmet que les paquets de données réellement perdus.
L'expéditeur a envoyé plusieurs paquets 1, 2, 3, 4 et 5, puis a reçu l'ACK de l'extrémité distante : 1, 3, 4, 5. Lors de la réception de l'ACK3, KCP savait que 2 avait été ignoré une fois et a reçu l'ACK4. est reçu, on sait que le paquet 2 a été sauté deux fois. A ce moment, on peut considérer que le paquet numéro 2 est perdu il n'est pas nécessaire d'attendre l'expiration du délai et le paquet numéro 2 peut être directement retransmis, ce qui s'améliore grandement. la vitesse de transmission lorsque des paquets sont perdus.
Afin d'utiliser pleinement la bande passante, TCP retarde l'envoi d'ACK (NODELAY est inutile). De cette façon, le calcul du délai d'attente calculera un temps RTT plus long, ce qui prolongera le processus de jugement en cas de perte de paquets. L'envoi différé de l'ACK de KCP peut être ajusté.
Il existe deux types de réponses de modèle ARQ, UNA (tous les paquets avant ce numéro ont été reçus, comme TCP) et ACK (les paquets avec ce numéro ont été reçus). L'utilisation de UNA seule entraînera toutes les retransmissions, tandis que l'utilisation d'ACK seule entraînera. un coût de perte trop élevé. Dans le passé, les protocoles consistaient uniquement à choisir l'un des deux, mais dans le protocole KCP, à l'exception des paquets ACK individuels, tous les paquets contiennent des informations UNA.
Le mode normal de KCP utilise la même règle de concession équitable que TCP, c'est-à-dire que la taille de la fenêtre d'envoi est déterminée par quatre facteurs : la taille du tampon d'envoi, la taille du tampon de réception restant à la réception, la concession de perte de paquets et le démarrage lent. Cependant, lors de la transmission de petites données avec des exigences de rapidité élevées, vous pouvez choisir d'ignorer les deux dernières étapes de la configuration et d'utiliser uniquement les deux premiers éléments pour contrôler la fréquence d'envoi. Au détriment de l'équité partielle et de l'utilisation de la bande passante, l'effet d'une transmission fluide peut être obtenu même lorsque BT est activé.
Vous pouvez télécharger et installer kcp à l'aide du gestionnaire de bibliothèque vcpkg :
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install kcp
La bibliothèque kcp dans vcpkg est tenue à jour par les membres de l'équipe Microsoft et les contributeurs de la communauté. Si la version est obsolète, veuillez créer un problème ou lancer un PR sur le référentiel vcpkg.
Créez un objet KCP :
// 初始化 kcp对象,conv为一个表示会话编号的整数,和tcp的 conv一样,通信双
// 方需保证 conv相同,相互的数据包才能够被认可,user是一个给回调函数的指针
ikcpcb *kcp = ikcp_create(conv, user);
Définir la fonction de rappel :
// KCP的下层协议输出函数,KCP需要发送数据时会调用它
// buf/len 表示缓存和长度
// user指针为 kcp对象创建时传入的值,用于区别多个 KCP对象
int udp_output ( const char *buf, int len, ikcpcb *kcp, void *user)
{
....
}
// 设置回调函数
kcp->output = udp_output;
Appelez la mise à jour en boucle :
// 以一定频率调用 ikcp_update来更新 kcp状态,并且传入当前时钟(毫秒单位)
// 如 10ms调用一次,或用 ikcp_check确定下次调用 update的时间不必每次调用
ikcp_update (kcp, millisec);
Entrez un paquet de couche inférieure :
// 收到一个下层数据包(比如UDP包)时需要调用:
ikcp_input (kcp, received_udp_packet, received_udp_size);
Après avoir traité la sortie/entrée du protocole de couche inférieure, le protocole KCP peut fonctionner normalement. Utilisez ikcp_send pour envoyer des données à l'extrémité distante. L'autre extrémité utilise ikcp_recv(kcp, ptr, size) pour recevoir des données.
Le mode par défaut du protocole est un ARQ standard, et divers commutateurs d'accélération doivent être activés via la configuration :
Mode de fonctionnement :
int ikcp_nodelay (ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
Fenêtre maximale :
int ikcp_wndsize (ikcpcb *kcp, int sndwnd, int rcvwnd);
Cet appel définira la taille maximale de la fenêtre d'envoi et la taille maximale de la fenêtre de réception du protocole, qui est par défaut de 32. Cela peut être compris comme SND_BUF et RCV_BUF de TCP, mais les unités sont différentes. L'unité SND/RCV_BUF est en octets, et cette unité est en octets. paquets.
Unité de transmission maximale :
Le protocole d'algorithme pur n'est pas responsable de la détection du MTU. Le mtu par défaut est de 1 400 octets. Vous pouvez utiliser ikcp_setmtu pour définir cette valeur. Cette valeur affectera l'unité de transmission maximale lors de la combinaison et de la fragmentation des paquets de données.
RTO minimum :
Qu'il s'agisse de TCP ou de KCP, il existe une limite RTO minimale lors du calcul du RTO. Même si le RTO calculé est de 40 ms, puisque le RTO par défaut est de 100 ms, le protocole ne peut détecter la perte de paquets qu'après 100 ms. En mode rapide, il est de 30 ms. Cette valeur peut être modifiée manuellement :
kcp->rx_minrto = 10 ;
L'utilisation et la configuration du protocole sont très simples. Dans la plupart des cas, vous pouvez l'utiliser après avoir lu le contenu ci-dessus. Si vous avez besoin d'un contrôle plus précis, comme changer l'allocateur de mémoire de KCP, ou si vous avez besoin de planifier plus efficacement les connexions KCP à grande échelle (par exemple plus de 3 500), ou comment mieux intégrer TCP, vous pouvez alors continuer la lecture :
Lecture connexe : « Genshin Impact » utilise également KCP pour accélérer l'actualité du jeu
KCP a été exécuté avec succès sur plusieurs projets avec des centaines de millions d'utilisateurs, leur offrant une expérience réseau plus réactive et plus fluide.
Bienvenue pour nous dire plus de cas
Si le réseau ne reste jamais bloqué, alors KCP/TCP se comportera de la même manière, mais le réseau lui-même n'est pas fiable, et la perte de paquets et la gigue sont inévitables (sinon, pourquoi aurions-nous besoin de divers protocoles fiables) ? Lorsqu'on compare directement dans un environnement presque idéal tel que l'intranet, tout le monde est presque pareil. Cependant, lorsqu'il est placé sur le réseau public, sur un réseau 3G/4G ou en utilisant la simulation de perte de paquets intranet, l'écart devient évident. Le réseau public connaît une perte moyenne de paquets proche de 10 % en période de pointe, et c'est encore pire en WiFi/3g/4g, ce qui entraînera des retards de transmission.
Merci à zhangyuan, l'auteur d'asio-kcp, pour une évaluation horizontale de KCP, enet et udt. Les conclusions sont les suivantes :
Pour plus de détails, voir : Les données de comparaison horizontale et d’évaluation fournissent davantage de conseils à ceux qui hésitent à choisir.
Le moteur de serveur de jeu massivement multijoueur SpatialOS a fait la même évaluation que TCP/RakNet après avoir intégré le protocole KCP :
Nous avons comparé le temps de réponse en conservant 50 caractères en même temps avec un taux de rafraîchissement de 60 Hz côté serveur. Veuillez consulter le rapport de comparaison détaillé :
Ces dernières années, les jeux en ligne et les différents réseaux sociaux ont connu une croissance exponentielle. Qu'il s'agisse de jeux en ligne ou de divers réseaux sociaux interactifs, l'interactivité et la complexité augmentent rapidement et ils doivent tous fournir des données simultanément dans un délai très court. des utilisateurs, la technologie de transmission deviendra naturellement un facteur important limitant le développement futur, et divers protocoles de transmission bien connus dans le monde open source, tels que raknet/enet Par exemple, lorsqu'une version est réalisée, l'ensemble de la pile de protocoles est publié ensemble. Cette forme n'est pas propice à la diversification. Mon projet ne peut choisir que de vous utiliser ou non. Il est difficile de choisir « vous utiliser partiellement », mais vous concevez. un ensemble de piles de protocoles, aussi bon soit-il, il est très difficile de répondre à divers besoins sous différents angles.
Par conséquent, la méthode de KCP consiste à « désassembler » la pile de protocoles afin que chacun puisse l'ajuster et l'assembler de manière flexible en fonction des besoins du projet. Vous pouvez ajouter une couche de code d'effacement de Reed Solomon ci-dessous pour FEC et une couche au-dessus pour RC4/Salsa20. Pour le chiffrement de flux, un échange de clé asymétrique est conçu lors de la prise de contact et un système de routage dynamique est construit au niveau de la couche de transport UDP sous-jacente pour détecter plusieurs chemins en même temps et sélectionner le meilleur chemin de transmission. Ces différentes « unités de protocole » peuvent être librement combinées selon les besoins, comme des éléments de base, pour garantir la « simplicité » et la « détachabilité », afin qu'elles puissent s'adapter de manière flexible aux besoins changeants de l'entreprise. Si un module n'est pas bon, il suffit de le remplacer.
Les futures solutions de transmission doivent être profondément personnalisées en fonction des scénarios d'utilisation, c'est pourquoi nous donnons à chacun une « unité de protocole » qui peut être librement combinée pour faciliter l'intégration dans votre propre pile de protocoles.
Pour plus d’informations, veuillez consulter les témoignages de réussite.
Auteur : Lin Wei (skywind3000)
Bienvenue à me suivre sur : blog personnel et Twitter.
Au cours de mes nombreuses années d'expérience en développement, j'ai toujours aimé étudier et résoudre certains problèmes de goulot d'étranglement dans les programmes. Dans mes premières années, j'ai aimé le développement de jeux, j'ai suivi la « programmation VGA » pour créer des graphiques de jeux et j'ai lu le « Programme graphique » de Michael Abrash. Guide du développeur" pour effectuer un rendu doux. J'aime jouer avec du code qui peut extraire le processeur et fonctionner plus rapidement. Après avoir rejoint le travail, mon intérêt s'est déplacé vers les technologies côté serveur et liées au réseau.
En 2007, après avoir créé plusieurs jeux traditionnels, j'ai commencé à étudier le problème de synchronisation des jeux d'action rapide. Au cours de cette période, j'ai été l'une des premières personnes en Chine à étudier les problèmes de synchronisation. peu importe comment résoudre la synchronisation, nous devons faire quelque chose en termes de transmission réseau. Après avoir quitté le jeu et être passé à Internet, j'ai également découvert que de nombreux domaines avaient ce besoin, j'ai donc commencé à passer du temps dans le domaine de la transmission réseau. , en essayant d'implémenter des protocoles conservateurs et fiables basés sur UDP, et en imitant le code de BSD Lite 4.4 pour implémenter des protocoles de type TCP. protocole, je l'ai trouvé assez intéressant, puis j'ai implémenté quelques jouets liés au P2P et aux réseaux de routage dynamique. Le protocole KCP est né en 2011. Il s’agit essentiellement d’un des nombreux jouets fabriqués par lui-même en termes de transmission.
L'auteur de Kcptun, xtaci, est mon camarade de classe. Nous nous spécialisons tous les deux en communication et étudions souvent ensemble comment optimiser la transmission.
Bienvenue à utiliser Alipay pour scanner le code QR ci-dessus afin de faire un don à ce projet. Les dons seront utilisés pour optimiser continuellement le protocole KCP et améliorer la documentation.
Merci à : 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 , Hua Bin, Rutao, Hu Jian. . . (Je suis désolé de ne pas avoir enregistré la liste précédente) Nous attendons les dons et le soutien de nos camarades de classe.
Bienvenue à faire attention
Groupe de communication KCP : 364933586 (numéro de groupe QQ), intégration KCP, réglage, transmission réseau et discussions techniques associées
Groupe Gitter : https://gitter.im/skywind3000/KCP
blog : http://www.skywind.me
Ce projet existe grâce à toutes les personnes qui y contribuent.