9 KCP
约 1196 字大约 4 分钟
2025-06-22
kcp是基于udp的有流量控制的可靠传输 以10%-20%带宽浪费的代价换取了比TCP快30%-40%的传输速度
kcp协议头
- [0,3]conv:连接号。UDP是无连接的,conv用于表示来自于哪个客户端。对连接的一种替代
- [4]cmd:命令字。如,IKCP_CMD_ACK确认命令 IKCP_CMD_WASK接收窗口大小询问命令, IKCP_CMD_WINS接收窗口大小告知命令,
- [5]frg:分片,用户数据可能会被分成多个KCP包,发送出去, 比如用户数据被分成4个分片:报文模式的值如3、2、1、0;流模式如0、0、0、0
- [6,7]wnd:接收窗口大小,发送方的发送窗口不能超过接收方给出的数值
- [8,11]ts:时间序列
- [12,15]sn:序列号
- [16,19]una:下一个可接收的序列号。其实就是确认号,收到sn=10的包,una为11
- [20,23]len:数据长度
- data:用户数据,这一次发送的数据长度
kcp的特性
- RTO翻倍vs不翻倍: TCP超时计算是RTOx2,这样连续丢三次包就变成BTOX承轮或空格分恐怖而KCP启动快速模式后不x2,只是x1.5(实验证明1.5这个值相对比较好),提高了传输速度。以RTO=100ms为例:
重传 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
TCP | 200 | 400 | 800 | 1600 |
UDP | 200 | 300 | 450 | 675 |
选择性重传vs全部重传:音视频应用 TCP丢包时会全部重传从丢的那个包开始以后的数据,KCP是选择性重传,只重传真正丢失的数据包。
快速重(跳过多少个包马上重传)(如果使用了快速重传,可以不考虑RTO)): 发送端发送了1,2,3,4,5几个包,然后收到远端的ACK:1,3,4,5,当收到ACK3时,KCP知道2被跳过1次,收到ACK4时,知道2被跳过了2次,此时可以认为2号丢失,不用等超时,直接重传2号包,大大改善了丢包时的传输速度。fastresend=2
延迟ACK VS 非延迟ACK: TCP为了充分利用带宽,延迟发送ACK(NODELAY-针对发送的都没用),这样超时计算会算出较大RTT时间,延长了丢包时的判断过程。KCP的ACK是否延迟发送可以调节。
UNA VS ACK+UNA: ARQ模型响应有两种,UNA(此编号前所有包已收到,如TCP)和ACK(该编号包已收到),光用UNA将导致全部重传,光用ACK则丢失成本太高,以往协议都是二选其一,而KCP协议中,除去单独的ACK包外,所有包都有UNA信息。
非退让流控: KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收端剩余接收缓存大小、丢包退让及慢启动这四要素决定。但传送及时性要求很高的小数据时,可选择通过配置跳过后两步,仅用前两项来控制发送频率。以牺牲部分公平性及带宽利用率之代价,换取了开着BT都能流畅传输的效果。
kcp配置模式
- 工作模式:
int ikcp_nodelay(ikcpcb* kcp,int nodelay,int interval,int resend,int nc)
nodelay:是否启用nodelay模式,0不启用;1启用。 interval:协议内部工作的interval,单位毫秒,比如10ms或者20ms resend:快速重传模式,默认o关闭,可以设置2(2次ACK跨越将会直接重传) nc:是否关闭流控,默认是0代表不关闭,1代表关闭。 默认模式:ikcp_nodelay(kcp,0,10,0,0);越极速走 普通模式:ikcp_nodelay(kcp,0,10,0,1);关闭流控等 极速模式:ikcp_nodelay(kcp,2,10,2,1),并且修改kcp1->rx_minrto=10; kcp1->fastresend =1;
越急速越浪费带宽
- 最大窗口:
int ikcp_wndsize(ikcpcb* kcp,int sndwnd,int rcvwnd);
该调用将会设置协议的最大发送窗口和最大接收窗口大小,默认为32,单位为包。
- 最大传输单元:
int ikcp_setmtu(ikcpcb* kcp,int mtu);+
kcp协议并不负责探测MTU,默认mtu是1400字节
- 最小RTO:不管是TCP还是KCP计算RTO时都有最小RTO的限制,即便计算出来RTO为40ms,由于默认的RT0是100ms,协议只有在100ms后才能检测到丢包,快速模式下为30ms,可以手动更改该值:kcp->rx_minrto=10;
常用命令
cmd | 作用 |
---|---|
IKCP_CMD_PUSH | 数据推送命令 |
IKCP_CMD_ACK | 确认命令 |
IKCP_CMD_WASK | 接收窗口大小询问命令 |
IKCP_CMD_WINS | 接收窗口大小告知命令 |
IKCP_CMD_PUSH和IKCP_CMD_ACK关联 | |
IKCP_CMD_WASK和IKCP_CMD_WINS关联 | |
IKCP_CMD_ACK是确认单独的包。 |
贡献者
版权所有
版权归属:PinkDopeyBug