KCP源码解析系列(一)KCP协议介绍

server/2024/9/23 11:17:37/

一、什么是KCP

TCP是为流量设计的(每秒内可以传输多少KB的数据),讲究的是充分利用带宽。而 KCP是为流速设计的(单个数据包从一端发送到一端需要多少时间),以10%-20%带宽浪费的代价换取了比 TCP快30%-40%的传输速度。TCP信道是一条流速很慢,但每秒流量很大的大运河,而KCP是水流湍急的小激流。

1.1 代码仓库

https://github.com/skywind3000/kcp

1.2 KCP在网络协议中的位置

在这里插入图片描述

二、KCP协议特点

kcp 是一个快速可靠ARQ协议,相比于tcp,以 10%-20% 带宽浪费的代价换取了快 30%-40% 的传输速度。kcp 可以看做应用层协议,底层采用 udp 传输。

2.1 RTO不翻倍

RTO(Retransmission TimeOut),重传超时时间。TCP的RTO是指数翻倍的,当网络比较差的时候,指数延长RTO时间。因为TCP是大公无私的,如果发现网络状况持续较差,就会放慢自己的发送速度。而KCP就比较自私,网络比较差了基本还是照常发。

tcp x 2,kcp x 1.5,提高传输速度

2.2 选择重传

TCP丢包时会全部重传从丢失包开始之后的数据,而KCP会选择性的重传,只重传真正丢失的数据包。

2.3 快速重传

  • 超时重传:超过规定的时间 RTO 则重传

  • 快速重传:收到fastresend个冗余ack,不去等待RTO ,直接重传

2.4 非延迟ACK

TCP为了充分利用带宽,延迟发送ACK,RTT时间比较大,演唱了丢包时的判断过程。而KCP的ACK是否延迟发送可以调节。

在这里插入图片描述

在这里插入图片描述

2.4 UNA vs ACK + UNA

ARQ模型响应有两种,UNA(此编号前所有包已收到,如TCP)和ACK(该编号包已收到),光用UNA将导致全部重传,光用ACK则丢失成本太高,以往协议都是二选其一,而 KCP协议中,除去单独的 ACK包外,所有包都有UNA信息。

2.5 非退让流控

KCP(Kernel Congestion Protocol)中的非退让流控是其流控制机制的一个特点。
在传统的 TCP 协议中,当检测到网络拥塞时,会采取比较保守的退让策略,例如降低发送窗口大小以减少数据发送量。
而 KCP 的非退让流控相对更积极和激进。它不会像 TCP 那样轻易地大幅度降低发送速率,而是会在一定程度上保持较高的发送速度,并通过快速的重传和窗口调整机制来适应网络状况。
这种非退让的流控方式在一些对延迟和实时性要求较高的场景中,可能会有更好的性能表现,但也需要更精细的参数配置和对网络环境的准确判断,以避免过度占用网络资源导致拥塞加剧。

三、KCP基本使用

kcp的使用非常的简单,基本和socket差不多。

3.1 初始化

ikcpcb *kcp = ikcp_create(conv, user);
// 示例中,conv 是会话编号,通信双方需要保证conv相同,user 是用户自定义数据,可以用于在回调函数中传递上下文

3.2 设置发送回调

//kcp协议的输出函数,当kcp需要发送消息的时候,需要调用它
static int on_kcp_output(const char *buf, int len, ikcpcb *kcp, void *user_data){......
}kcp->output = on_kcp_output;

kcp_update_79">3.3 循环调用ikcp_update

ikcp_update是整个kcp事件驱动的核心,kcp数据的发送和接收都需要ikcp_update来完成。

    // 主循环while (true) {IUINT32 current = iclock();if (current >= nextUpdateTS) {ikcp_update(kcp, current);nextUpdateTS = ikcp_check(kcp, current); // 确定下次调用时间}// 计算到下次`ikcp_update`的时间IINT32 sleepTime = nextUpdateTS - iclock();if (sleepTime > 0) {usleep(sleepTime * 1000);  // 把睡眠时间转换为微秒} else {// 当 sleepTime <= 0 时,确保继续循环以避免错过更新时机usleep(1000); // 产生小的延迟,让出 CPU 资源}// 可以在这里处理其他网络事件,如接收数据包、发送数据// 例如:// recvData();// sendData();}

3.4 输入数据包

当udp收到数据包时,通过ikcp_input输入给kcp协议

ikcp_input(kcp, buffer, len);

3.5 收发数据

ikcp_send(kcp, buffer, len);
int len = ikcp_recv(kcp, buffer, sizeof(buffer));

http://www.ppmy.cn/server/99543.html

相关文章

将电脑打造成私人网盘,支持外网访问之详细操作教程

你想过把自己电脑打造成随时随地访问的网盘吗&#xff1f;就是那种拥有一个属于自己的影音库&#xff0c;不用担心被和谐&#xff0c;随时可以登录访问电脑上的各种文件&#xff0c;相比传统网盘省心又安全。 使用Everything和节点小宝将电脑搭建成私人网盘&#xff0c;可以实现…

善用 AI ,优化项目,保姆级简历写作指南第七弹

大家好&#xff0c;我是程序员鱼皮。做知识分享这些年来&#xff0c;我看过太多简历、也帮忙修改过很多的简历&#xff0c;发现很多同学是完全不会写简历的、会犯很多常见的问题&#xff0c;不能把自己的优势充分展示出来&#xff0c;导致错失了很多面试机会&#xff0c;实在是…

《Unity3D高级编程 主程手记》第四章 用户界面(六) UI 优化(上)

从以下几个方面进行 UI 优化&#xff1a; UI 动静分离拆分 UI预加载Alpha 分离字体拆分滚屏优化网格重构优化UI 展示与关闭的优化对象池的运用贴图设置的优化内存泄漏针对高低端机型的优化图集拼接的优化UI 业务逻辑中GC的优化 4.6.1 UI 动静分离 什么是UI动静分离&#xff1f…

设计模式 - 单例模式

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、单例模…

C语言基础编程题:第 k 小整数(C语言版,采用冒泡排序)

1.题目描述 现有n个正整数&#xff0c;要求出这 n 个正整数中的第k个最小整数(相同大小的整数只计算一次)。 输入格式 第一行为 n 和 k; 第二行开始为 n 个正整数的值&#xff0c;整数间用空格隔开。 2.输出格式 第k个最小整数的值;若无解&#xff0c;则输出NO RESULT。 3.输…

WordPress原创插件:Download-block-plugin下载按钮图标美化

WordPress原创插件&#xff1a;Download-block-plugin下载按钮图标美化 https://download.csdn.net/download/huayula/89632743

ArcGIS Pro 3.1学习之旅 ----day01 Arcgis pro安装

我们付出一些成本&#xff0c;时间的或者其他&#xff0c;最终总能收获一些什么。 前几个月&#xff0c;一时兴起&#xff0c;学了一个月的FME,但由于个人工作环境等原因&#xff0c;能够一起进行学习技术交流的环境不够。短暂的学习后&#xff0c;没有足够的应用场景&#xf…

网络中特殊的 IP 地址

特殊网络 IP 127.0.0.1 127.0.0.1 是本机回送地址&#xff0c;发送到 127.0.0.1 的数据或者从 127.0.0.1 返回的数据只会在本机进行传输, 而不进行外部网络传输。 主要有以下两个作用&#xff1a; 测试本机网络 当我们可以 ping 通 127.0.0.1 的时候, 则说明本机的网卡以及 tc…