KCP C# 版本 源码解析

 

源码地址:https://github.com/KumoKyaku/KCP

-----------------------------------------

  • 问题来了:怎么才能让服务器发送一个带ACK或UNA的包?

答案:接收方的 KCP acklist在每次收到对方的数据包时,会收集sn序列号,然后Flush的时候,封装成ACK包回给对方。
-----------------------------------------

  • 问题来了:KCP接收端如何拼包,以确保可靠性传输?
  • 转换问题:KCP源码中几个关键的发送接收队列与缓冲的作用是什么?

KCP Send ,对用户的数据根据mss值进行分片,然后将分片后的数据放入snd_queue。
KCP Flush,每次被调用的时候遍历出队snd_queue(条件为snd_nxt < snd_una + cwnd_)。
对每个seg的sn与una编号,cmd = IKCP_CMD_PUSH,进行初始化后,放入snd_buf。
之后立即对current_, segment.resendts进行比较,决定每个元素是否重传发送,
KCP Input,如果cmd为PUSH,则记录每个包的sn进acklist队列。
然后新建一个KcpSegment,将数据考入其中,再放入rcv_buf
紧接着,循环遍历rcv_buf,看队头是不是我们恰恰想要的rcv_nxt,如果是则加入rcv_queue中。
KCP PeekSize,rcv_queue队头元素的frg记录着发送方此次分包的数量,若rcv_queue次数的队列元素个数等于它,则说明所有的分包都已收到。
KCP Recv,如若PeekSize返回大于0,则可以此函数取一个完整的UDP数据包,此函数内部会对rcv_queue内所有元素的数据进行解包merge,
最后清除掉rcv_queue。

---------------------------------------------

  • 问题来了:他的超时重传机制有何优势?

TCP滑动窗口与KCP窗口机制的比较
1、TCP的滑动窗口,采用累积确认的方式,对按序到达的最后一个分组发送确认,如发送方发送了10个分组,第3个分组丢失了,则接收方只能
对前2个分组发送确认,而发送方必须把3~8个分组全部重传。如果网络情况不好,这可能会带来不好的影响。
2、KCP的窗口,接收方会为发送方的每个分组都发送回复(sn),也会采用TCP模式对若干连续分组统一回复(una),这样的混合模块,增加了
带宽负担,但是在网络情况不好的时候,可以减少发送方的重传负担。

----------------------------------------------

 

上一篇:.net爬虫是一门必修课


下一篇:7-34 求分数序列前N项和 (15 分)