SkywindInside快速可靠协议.docxVIP

  • 4
  • 0
  • 约3.21千字
  • 约 8页
  • 2021-03-23 发布于山东
  • 举报
Skywind Inside 快速可靠协议 KCP 是一个快速可靠协议,能以比 TCP 浪费 10%-20% 的带宽的代价,换取平均延迟降低 30%-40% ,且最大延迟 降低三倍的传输效果。纯算法实现,并不负责底层协议(如 UDP )的收发,需要使用者自己定义下层数据包的发送方式, 并以 callback 的方式提供给 KCP 。连时钟都需要外部传递 进来,内部不会有任何一次系统调用。 整个协议只有 ikcp.h, ikcp.c 两个源文件, 可以方便的集成到 用户自己的协议栈中。也许你实现了一个 P2P,或者某个基 于 UDP 的协议,而缺乏一套完善的 ARQ 可靠协议实现, 那么简单的拷贝这两个文件到现有项目中,稍微编写两行代 码,即可使用。 URL :/skywind3000/kcp 技术特性 TCP 是为流量设计的(每秒内可以传输多少 KB 的数据), 讲究的是充分利用带宽。 而 KCP 是为流速设计的 (单个数据 包从一端发送到一端需要多少时间) ,以 10%-20% 带宽浪费 的代价换取了比 TCP 快 30%-40% 的传输速度。 TCP 信道是 一条流速很慢, 但每秒流量很大的大运河, 而 KCP 是水流湍 急的小激流。 KCP 有正常模式和快速模式两种,通过以下策 略达到提高流速的结果: 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(该编号包已收到) ,KCP有单独 ACK ,且数据包和 ACK 包都带 UNA 信息,有效降低 ACK 丢失成本。 非退让流控: KCP 正常模式同 TCP 一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收端剩余接收缓存大 小、丢包退让及慢启动这四要素决定。但传送及时性要求很高的小数据时,可选择通过配置跳过后两步,仅用前两项来控制发送频率。以牺牲部分公平性及带宽利用率之代价,换取了开着 BT 都能流畅传输的效果。 基本使用 创建 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-gt;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(kcp, ptr, size) 来向远端发送数据。 而另一端使用 ikcp_recv(kcp, ptr, size) 来接收数据。

文档评论(0)

1亿VIP精品文档

相关文档