6

KCP协议浅析 - 寡人正在Coding

 1 year ago
source link: https://www.cnblogs.com/hggzhang/p/17235879.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

  博客园  ::

首页  ::

新随笔  ::

联系 ::

订阅

 ::

管理

  19 随笔 :: 0 文章 :: 0 评论 ::

6431 阅读

KCP协议结合了TCP和UDP协议的特点,是一个快速可靠的协议。
引述官方介绍:

KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据的发送方式,以 callback的方式提供给 KCP。连时钟都需要外部传递进来,内部不会有任何一次系统调用。
TCP是为流量设计的(每秒内可以传输多少KB的数据),讲究的是充分利用带宽。而 KCP是为流速设计的(单个数据从一端发送到一端需要多少时间),以10%-20%带宽浪费的代价换取了比 TCP快30%-40%的传输速度。

传统的TCP/UDP协议见参考链接。

| 4bit conv | 1bit cmd | 1bit frg | 2bit wnd |
| 4bit ts | 4bit sn |
| 4bit una | 4bit len |
| anybit 数据 |

  • conv:会话序号,通信双方一致
  • cmd:报文类型
    • IKCP_CMD_ACK 确认
    • IKCP_CMD_PUSH 数据推送
    • IKCP_CMD_WASK 接收窗口查询大小
    • IKCP_CMD_WINS 接收窗口大小告知
  • wnd: 己方可用接收窗口大小,接收窗口大小 - 接收队列大小
  • frg:包分片(数量)
  • sn: 包分片序号
  • ts: 时间戳,用于计算RTO和RTT
  • una:待接收的序列号(确认号),表示该序列号之前的所有报文都收到了,可以删除
  • len:用户数据长度
  • 数据:用户数据

RTO不翻倍

RTO(Retransmission-TimeOut)即重传超时时间,TCP和KCP是基于ARQ协议实现的可靠性,但TCP的超时计算是RTO2,而KCP的超时计算是RTO1.5,也就是说假如连续丢包3次,TCP是RTO8,而KCP则是RTO3.375,意味着可以更快地重新传输数据。

选择性重传

tcp 丢包时会全部重传从该包开始以后的数据,而 kcp 选择性重传,只重传真正丢失的数据包。

收到fastresend(配置)个失序报文后,不等待超时,直接重传,减少丢包等待时间。
而TCP重传模式:

  • 超时重传:超过规定的时间 RTO 则重传
  • 快速重传:收到三个冗余ACK,不去等待 RTO ,直接重传

与TCP相同,都是通过累计确认实现的,发送端发送了1,2,3,4,5几个包,然后收到远端的ACK:1,3,4,5,当收到ACK = 3时,KCP知道2被跳过1次,收到ACK = 4时,知道2被跳过了2次,此时可以认为2号丢失,不用等超时,直接重传2号包,大大改善了丢包时的传输速度。

非延迟 ACK

停等ARQ协议

image
  • A会为每个即将发送的数据编号,编号的目的是为了标识数据和给数据排序
  • A发送完数据之后,会给这次发送的数据设置一个超时计时器
  • B收到数据,将会返回一个确认,该确认也有自己的编号
  • A收到确认,将删除副本且取消超时计时器,保留副本的原因是传输可能出错
  • B收到错误的数据,或者数据在传输过程中出错,总之就是说B没有收到想要的数据
  • A在超时计时器的设置时间内没有收到确认,此时重发数据

所以可靠的TCP有32位序列号和32位确认号,TCP和UDP都有16位校验和。

连续ARQ协议

image

连续ARQ协议不会响应每个数据段,而是仅仅响应编号最大的这个数据段,表示之前的数据都收到了,这个叫做UNA模式,而停等ARQ协议可以看作是ACK模式

ACK + UNA

ARQ (自动重传请求,Automatic Repeat-reQuest)模型响应有两种方式:

  • UNA:此编号前所有包已收到
  • ACK:该编号包已收到

只用 UNA 将导致全部重传,只用 ACK 则丢失成本太高,以往协议都是二选其一。而 kcp 协议中,除去单独的 ACK 包(精确)外,所有包都有 UNA 信息

非退让流控

KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收端剩余接收缓存大小、丢包退让、慢启动这四要素决定,慢启动是在刚开始发送数据时让窗口缓慢扩张,退半避让是在网络拥堵时窗口大小减半,快重传是在网络恢复时及时给予响应,与之配合的就是快恢复。但传送及时性要求很高的小数据时,可选择仅用前两项来控制发送频率。以牺牲部分公平性及带宽利用率之代价,换取了流畅传输的效果。KCP 实时性好,但带宽利用率较低,因为:

  • 非退让流控,不断尝试发送数据,有效包不多
  • 每个包应答,占用一定的带宽

窗口协议中有两种:

  • 拥塞窗口:防止过多的数据注入到网络中,这样可以使网络中的路由器 和链路不至于过载。
  • 滑动窗口:接收方告知发送方自己可以接收缓冲区的大小,通常与连续ARQ协议配合使用。
image

大概流程如图示,若是想深入探索底层实现,请参考源码或者参考链接中的详解


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK