玩转KCP(3)-流量控制
版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 KCP协议的很多东西都是脱胎于TCP协议,所以他们在思想和实现上是完全相通的。xtaci/kcp-go 包含FEC也不过4000多行代码,skywind3000/kcp 主要是C/C++的代码,也就2000多行,萌叔建议大家都去阅读下源码。 慢启动、拥塞避免、拥塞发生、快速重传,这些概念都非常唬人,但看完代码你会发现不过尔尔。 在开始正式的文章之前,萌叔打算问几个问题? 流控是为了保护谁? 在实现中如何体现? 2. 流控是为了保护谁? TCP是全双工,这里简化一下,我们只看半双工的情况 Sender发送数据给Receiver 1) Sender中的应用程序把数据写入到本机的发送缓冲区 2) 数据从发送缓冲区写入到链路中,链路可能是由实际的光缆、电缆、多个路由器节点组成。 3)数据从链路转交到Receiver的接收缓冲区 4)数据从接收缓冲区交给Receiver的应用程序 发送缓冲区大小是有限的,它必须被保护起来 Sender和Receiver之间的链路的收发能力也是有限的,且是与网络中的其它节点共享的,因此Link也必须受到保护 接收缓冲区大小也是受限的,它也应该受到保护 3. 在实现中如何体现? 在实际实现中每一个需要保护的点,都有与之对应的参数,先上结论 3.1 使用发送端的发送窗口(snd_wnd)保护本机的发送缓冲区 3.2 使用拥塞窗口(cwnd)来保护发送端与接收端之间的链路 cwnd是动态变化的值, 算法与TCP协议基本相同 3.3 使用接收端的接收窗口(rmt_wnd, 表示接收窗口的空闲大小)保护接收端的接收缓冲区 rmt_wnd对应KCP协议的wnd, 由接收端汇报 回顾一下KCP协议 0 4 5 6 8 (BYTE) +---------------+---+---+-------+ | conv |cmd|frg| wnd | +---------------+---+---+-------+ 8 | ts | sn | +---------------+---------------+ 16 | una | len | +---------------+---------------+ 24 | | | DATA (optional) | | | +-------------------------------+ 4. 分析一次完整的写入动作 4.1 发送窗口和接收窗口对写入的影响 在KCP中,数据被拆分成Segment后 ...