网络篇01 | kcp(王者荣耀)

网络篇01 | kcp(王者荣耀)

  • 01 kcp报文格式
  • 02 名词说明
  • 03 技术特点
    • 超时重传时间
    • 超时重传机制
    • 快速重传机制
    • ACK机制对比
    • 收包确认机制对比
    • 非退让流控
  • 04 kcp参数
  • 05 kcp配置模式

kcp是一个快速可靠协议(也可以叫udp的可靠性传输)。结合了tcp的可靠性和udp的传输速度等优点,能以⽐ TCP浪费10%-20%带宽的代价,换取平均延迟降低 30%-40%,且 最⼤延迟降低三倍的传输效果。使用纯算法实现,不负责底层协议(如udp)的收发,内部没有系统调用。

01 kcp报文格式

https://gitee.com/tipsdark/kcp-netty.git
网络篇01 | kcp(王者荣耀)_第1张图片

  • conv :连接号。UDP是⽆连接的,conv⽤于表示来⾃于哪个客户端。对连接的⼀种替代, 因为有 conv , 所以KCP也是⽀持多路复⽤的。
  • cmd :命令类型,只有四种。
    IKCP_CMD_ACK,确认命令;
    IKCP_CMD_PUSH,数据推送命令;
    KCP_CMD_WASK,接收窗⼝⼤⼩询问命令;
    IKCP_CMD_WINS,接收窗⼝⼤⼩告知命令。
  • frg :分⽚,⽤户数据可能会被分成多个KCP包,发送出去。
  • wnd :接收窗⼝⼤⼩,发送⽅的发送窗⼝不能超过接收⽅给出的数值, (其实是接收窗⼝的剩余⼤⼩,这个⼤⼩是动态变化的)
  • ts : 时间序列
  • sn : 序列号
  • una :下⼀个可接收的序列号(连续的序列)。其实就是确认号,收到sn=10的包,una为11
  • len :数据⻓度(DATA的⻓度)
  • data :⽤户数据

02 名词说明

用户数据:应用层发送的数据,如一张图片2Kb的数据

  • MTU:最大传输单元。即每次发送的最大数据
  • RTO:Retransmission TimeOut,重传超时时间。
  • RTT: 一个报文段发送出去,到收到对应确认包的时间差。
  • cwnd:congestion window,拥塞窗口,表示发送方可发送多少个KCP数据包。与接收方窗口有关,与网络状况(拥塞控制)有关,与发送窗口大小有关。
  • rwnd:receiver window,接收方窗口大小,表示接收方还可接收多少个KCP数据包
  • snd_buf:发送消息的缓存,存放处于发送状态的数据(比如调用了sendto后)
  • snd_queue:待发送KCP数据包队列,暂存分片、排序后的数据,当发送缓存有空之后就会放入发送缓存。
  • snd_nxt:下一个即将发送的kcp数据包序列号
  • snd_una:下一个待确认的序列号
  • rcv_buf:接收消息的缓存, 还不能直接供用户读取的数据
  • rcv_queue:接收消息的队列, 是已经确认可以供用户读取的数据(已经排好序)

03 技术特点

超时重传时间

  • TCP超时计算是RTOx2,这样连续丢三次包就变成RTOx8了,⼗分恐怖;
  • ⽽KCP启动快速模式后不x2, 只是x1.5(实验证明1.5这个值相对⽐较好),提⾼了传输速度。

RTO(Retransmission-TimeOut)即重传超时时间,TCP是基于ARQ协议实现的可靠性,KCP也是基于ARQ协议实现的可靠性,但TCP的超时计算是RTO2,而KCP的超时计算是RTO1.5,也就是说假如连续丢同一个包3次,TCP第3次重传是RTO8,而KCP则是RTO3.375,意味着可以更快地重新传输数据。通过4字节ts计算RTT(Round-Trip-Time)即往返时延,再通过RTT计算RTO,ts(timestamp)即当前segment发送时的时间戳。

超时重传机制

  • TCP丢包时会全部重传从丢的那个包开始以后的数据;
  • KCP是选择性重传,只重传真正丢失的数据包。

快速重传机制

发送端发送了1,2,3,4,5⼏个包,如果2包丢失;

  • kcp快速重传机制为:收到远端回复的ACK: 1, 3, 4, 5,当收到ACK3时,KCP知道2被跳过1 次,收到ACK4时,知道2被跳过了2次,此时可以认为2号丢失,不⽤等超时,直接重传2号包,⼤⼤改善 了丢包时的传输速度。

ACK机制对比

  • TCP为了充分利⽤带宽,延迟发送ACK(NODELAY都没⽤),这样超时计算会算出较⼤ RTT时间,延⻓ 了丢包时的判断过程。
  • KCP的ACK是否延迟发送可以调节。

收包确认机制对比

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

非退让流控

  • KCP正常模式同TCP⼀样使⽤公平退让法则,即发送窗⼝⼤⼩由:发送缓存⼤⼩、接收端剩余接收缓存大小、丢包退让及慢启动这四要素决定。但传送及时性要求很⾼的⼩数据时,可选择通过配置跳过后两步,仅⽤前两项来控制发送频率。以牺牲部分公平性及带宽利⽤率之代价,换取了开着BT都能流畅传输的效果。

04 kcp参数

待补充。

05 kcp配置模式

1)工作模式:int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc)

nodelay :是否启用 nodelay模式,0不启用;1启用。
interval :协议内部工作的 interval,单位毫秒,比如 10ms或者 20ms
resend :快速重传模式,默认0关闭,可以设置2(2次ACK跨越将会直接重传)
nc :是否关闭流控,默认是0代表不关闭,1代表关闭
普通模式: ikcp_nodelay(kcp, 0, 40, 0, 0)
极速模式: ikcp_nodelay(kcp, 1, 10, 2, 1) 

2)最大窗口:int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd);

该调用将会设置协议的最大发送窗口和最大接收窗口大小,默认为32,单位为包。

3)最大传输单元:int ikcp_setmtu(ikcpcb *kcp, int mtu);

kcp协议并不负责探测MTU (最大传输单元),默认 mtu 是 1400 字节

3)最小RTO:

不管是 TCP还是 KCP计算 RTO时都有最小 RTO的限制,即便计算出来RTO为40ms,由于默认的 RTO是100ms,协议只有在100ms后才能检测到丢包,快速模式下为30ms,可以手动更改该值: kcp->rx_minrto = 10;

你可能感兴趣的:(netty4,网络,java,nio)