KCP:快速可靠的ARQ协议

2021-04-13 04:05:24

Permalink KCP是一种快速可靠的协议,可以实现平均等待时间的降低的传输效果30%至40%,并将最大延迟的最大延迟降低为三倍,成本为10%至20%更多的带宽浪费而不是TCP。它是通过使用纯算法实现的,并且不对底层协议(例如UDP)的发送和接收,要求用户为基础数据包定义自己的传输模式,并将其提供给KCP回调方式。即使是时钟需要从外部传递,没有任何内部系统调用。

整个协议只有两个ikcp.h,ikcp.c的源文件,可以很容易地集成到用户' s自己的协议栈中。您可能已经实现了P2P或基于UDP的协议,但缺少一组完美的ARQ可靠协议实现,然后通过简单地将两个文件复制到现有项目,并编写几行代码,您可以用它。

TCP专为流量而设计(可以传输的数据的每秒数量的数量),专注于充分利用带宽。虽然KCP专为流速而设计(从一端发送单个分组的时间),但带宽10%-20%的带宽浪费,以换取传输速度比TCP快30%-40%。 TCP频道是一个大运河,流量非常慢,但每秒非常大的流量,而KCP是一种迅速流动的洪流。 KCP具有正常和快速模式,通过以下策略实现流速的结果增加:

TCP超时计算是RTOX2,所以三个连续的数据包丢失将使它是RTOX8,这是非常可怕的,而在KCP快速模式启用后,它不是X2,但X1.5(实验结果表明值为1.5相对较好),它提高了传输速度。

当TCP中发生数据包丢失时,将重新发送丢失数据包后的所有数据,而KCP是选择性重传,并且只重新发送真正丢失的数据包。

发送终端发送1,2,3,4和5个分组,然后接收远程Ack:1,3,4和5,当接收到Ack3时,KCP知道2被跳过1次,并且当接收到Ack4时,它知道此时2次跳过2次,此时可以考虑2丢失,无需等待直到超时,它将直接重传数据包2,当发生数据包丢失时,可以大大提高传输速度。

为了充分利用带宽,TCP延迟发送ACK(甚至没有工作),因此超时计算将出现相对高的RTT,在发生丢包时已经扩展了判断过程。虽然对于KCP,但它是可调的是否延迟发送ACK。

ARQ模型响应有两种:UNA(此数字之前的所有数据包,例如TCP)和ACK(收到此号码的数据包)。单独使用UNA将导致完全重新传输,仅使用ACK对数据包丢失的成本太大,因此在先前的协议中,已选择其中一项;虽然在KCP协议中,除了单个ACK数据包之外,所有数据包都有UNA信息。

KCP Normal Mode使用与TCP相同的公平特许规则,即发送窗口大小由:四个因子包括发送缓存的大小,接收端的接收缓冲区的大小,数据包丢失特许权和慢速开始。但是,在使用高时的要求发送小数据时,允许通过配置选择跳过后两步,仅使用前两个项目来控制传输频率,牺牲一些公平和带宽利用率,以换取即使在BT打开时,也能效果。

VCPKG中的KCP端口由Microsoft团队成员和社区贡献者保持最新。如果版本过期,请在VCPKG存储库上创建问题或拉拔请求。

//初始化KCP对象,CONC是表示会话编号的整数,//与TCP的译文相同,两个通信方都应确保可以识别相同的数据包,用户是指针它将被传递给回调函数.ikcpcb * kcp = ikcp_create(dirm,用户);

// KCP下层协议输出功能,当IT //需要发送数据时,通过KCP调用,Buf / Len表示缓冲区和数据长度。 //用户是指将KCP对象创建到//区分多个KCP对象int Udp_output(const char * buf,int len,ikcpcb * kcp,void *用户){....} / /设置回调函数kcp->输出= udp_output;

//以某个频率调用ikcp_update以更新KCP状态,并通过//当前时钟(以毫秒为单位)。如果每10ms执行呼叫,或者// ikcp_check用于确定下一个呼叫更新的时间,则每次都不需要调用//; ikcp_update(kcp,millisec);

//在收到下层数据包(例如UDP数据包)时需要调用:ikcp_input(kcp,recepty_udp_packet,recepty_udp_size);

在处理下层协议的输出/输入后,KCP协议可以正常工作,并且ikcp_send用于将数据发送到远程端。另一端使用IKCP_RECV(KCP,PTR,大小)来接收数据。

协议默认模式是标准ARQ,可以通过配置启用各种加速交换机:

间隔:协议内部工作间隔,以毫秒为单位,例如10毫秒或20毫秒。

重新发送:快速重传模式,0表示默认值,可以设置2(2个ACK跨度将导致直接传输)

NC:是否关闭流量控制,0表示“请勿关闭”默认情况下,1表示“关闭”。

呼叫将设置MACHOTOL的最大发送窗口和最大接收窗口大小,默认为32。这可以被理解为TCP的SND_BUF和RCV_BUF,但该单元不相同,SND / RCV_BUF单位是字节,而本机是数据包。

纯算法协议不对MTU检测负责,默认MTU是1400字节,可以使用ikcp_setmtu设置。该值将影响数据包合并和碎片时的最大传输单元。

无论TCP还是KCP,它们都有限制在计算RTO时的最低RTO,即使计算出的RTO为40ms,因为默认RTO为100ms,该协议只能在100ms后检测数据包丢失,即在快速上为30ms模式,可以手动更改值:

协议的使用和配置都非常简单,在大多数情况下,阅读上述内容后,基本上您将能够使用它。如果您需要进一步的精细控制,例如更改KCP内存分配器,或者如果您需要更高效的KCP链接大规模调度(例如超过3,500个链接),或者更好地与TCP合并,您可以继续进行广泛的阅读:

KCPTUN:基于高速远程端口转发(隧道)在KCP-GO上,具有SSH-D,它允许比Finalspeef更顺畅的在线视频视图。

狗隧道:通过GO开发的网络隧道,使用KCP大大提高传输速度,并迁移了KCP的GO版本。

V2RAY:众所周知的代理软件,Shadowsocks更换,在1.17后与KCP协议集成,使用UDP传输,无数据包功能。

FRP:快速反转代理,以帮助您在NAT或防火墙后面将本地服务器曝光到Internet。

ASIO-KCP:使用KCP的完整UDP网络库,完成基于UDP的链路状态管理,会话控制和KCP协议调度等的完成实现。

KCP-Go:高安全性Go语言实现KCP,包括简单地实现UDP会话管理,作为后续开发的基本库。

KCP-CSharp:KCP的CSharp迁移,包含会话管理,可以访问上述KCP-Go Server。

nysocks:nysocks为NodeJS用户提供了Libuv和KCP的代理服务基础。客户端支持Socks5和SS协议。

Shadowsocks-android:Android的Shadowsocks使用KCP协议将KCPTUN集成,以加速Shadowsocks,具有良好的结果

Yasio:跨平台异步套接字库专注于任何具有KCP支持的客户端应用程序,易于使用,API与UDP和TCP相同,请参阅基准泵。

GOUXP:使用DECRING和FEC支持实现基于回调的KCP开发包,易于使用。

如果网络从未拥塞,则KCP / TCP性能类似;但网络本身不可靠,并且数据包丢失和抖动可能是不可避免的(否则为什么有各种可靠的协议)。在Intranet环境中是几乎理想的,它们具有类似的性能,但在公共互联网上,在3G / 4G网络情况下或使用Intranet丢失仿真,间隙很明显。公共网络平均在高峰时段内平均近10%的数据包丢失,这在WiFi / 3G / 4G网络中甚至更差,所有这些都将导致传输拥塞。

凭借张源的ASIO-KCP作者,在KCP,ENET和UDT上进行水平评估,结论如下: 当网络滞后发生时,滞后率小于1秒。 当滞后发生时,比eNET好3倍。 udt是个坏主意。 它总是陷入困境的速度超过秒数滞后。 并未预期恢复。 Enet有缺乏医生的问题。 它有很多功能,你可能会收集。 kcp' s doc在中文和英文中。 好东西是代码中编写的功能细节是英语。 你可以使用asio_kcp,这是一个很好的包装。 KCP是一件简单的事情。 如果您想要更多功能,您将编写更多代码。 UDT有一个完美的医生。 我的感受可能比其他人更多的虫子。

有关细节,请参阅:可靠的UDP基准和KCP-基准,以获取对犹豫用户的更多指导。 欢迎捐赠通过使用支付宝来欢迎,这笔钱将用于改进议定书和文件。