KCP源码解析系列(四)滑动窗口

KCP 的滑动窗口TCP 大体相同。倘若深入探究源码,便会发觉之前那些难以理解的理论,在实现方面只有寥寥几行代码。接下来,看看 KCP 是怎样达成这些机制的。

TCP的可靠传输的实现–滑动窗口

倘若您未曾了解过滑动窗口,不妨观看以下 12 分钟的视频。我敢赌 5 块钱,您看完后肯定能理解滑动窗口机制。

https://www.bilibili.com/video/BV194411h71z/?spm_id_from=333.337.search-card.all.click

KCP中的滑动窗口

窗口大小

kcp和TCP一样,也是全双工的,所以不单有发送窗口,也有接收窗口。

发送窗口由远端窗口和拥塞窗口共同决定。

	//发送窗口,调用ikcp_wndsize配置,默认32,
    kcp->snd_wnd = IKCP_WND_SND;
    //接收窗口,调用ikcp_wndsize配置,默认128,同时必须要大于128
	kcp->rcv_wnd = IKCP_WND_RCV;
    //对端窗口,接收端ack时,会将wnd带过来
	kcp->rmt_wnd = IKCP_WND_RCV;
    //拥塞窗口,动态计算,后边会讲到
	kcp->cwnd = 0;

发送方的滑动窗口控制

  • 发送方维护一个 snd_buf 队列,保存已经发送但尚未确认的 Segment。

  • 当发送新的 Segment 时,会检查 snd_wndcwnd,确保在窗口范围内发送。

  • 每次发送数据时,发送窗口滑动,新的数据包进入窗口,并放入 snd_buf 中。

接收方滑动窗口控制

  • 接收方维护一个 rcv_buf 队列,保存接收到但尚未处理的 Segment。

  • 当接收到一个新的 Segment 时,首先检查其是否在接收窗口范围内 (rcv_wnd)。

  • 接收窗口滑动,将新的数据包放入 rcv_buf,并从窗口中移除已经确认的数据包。

窗口滑动的实现(以发送窗口为例)

滑动窗口犹如节假日时的高铁站。在安检处,有一位工作人员把控着人员的入场。安检处外,人员有序地排着队,而安检处内同样存在一个小队伍,大家都在有条不紊地进行安检。这个小队伍的最大长度,就是窗口的大小,倘若安检处里的人员过多,工作人员便会禁止人员入场;一旦有一部分人完成安检得以放行,工作人员就会再度允许人员进入。

我们把第一个进入高铁站的人设置编号为0,然后接下来排队的人编号递增,

定义 snd.una为下一个进入高铁站的人员编号

定义 snd.nxt 为下一个进入安检口的人员编号,

那么 snd.nxt - send.una 就是安检处的人数,也就是发送了但未收到确认的的数据包的个数,

snd.una + snd.wnd - snd.nxt 就是还可以进入安检的人数,也就是可用窗口的大小。

编号小于snd.una的人,意味着已经进入高铁站了,我们就不用管了,

具体可以结合如下图示理解。

请添加图片描述
接收发送窗口的基本实现和发送窗口一致,具体参考下图,

请添加图片描述

滑动窗口的源码解析

滑动窗口中的队列
名称 作用 说明
snd_buf 存储已经发送但尚未收到 ACK 确认的数据段 当一个数据包被发送后,它会被放入 snd_buf 中,直到收到对端的确认 (ACK)。KCP 通过这个队列来追踪未确认的数据包,并在需要时进行重传
rcv_buf 存储接收到但尚未被应用层处理的数据段 当 KCP 接收到一个数据段时,如果该段是乱序到达的(即序列号不连续),它会被放入 rcv_buf 中。接收窗口在等待正确的序列号时,乱序数据会保留在这个队列中,直到可以被应用层处理
snd_queue 存储待发送的数据段 应用层调用 ikcp_send() 将数据传递给 KCP 协议栈后,数据会被切分成多个数据段并放入 snd_queue 中。KCP 会根据窗口大小和拥塞控制机制,从这个队列中取出数据段进行发送
rcv_queue 存储已经按照正确顺序接收的数据段,等待应用层处理 一旦数据段的序列号符合接收窗口的预期(即接收方期望的下一个序列号),这些数据段会被从 rcv_buf 移动到 rcv_queue 中,并等待应用层读取
snd_nxt的更新

只要发送窗口有空闲,就把send_queue中的数据移动到snd_buf

void ikcp_flush(ikcpcb *kcp)
{
   
   
    .....
	// calculate window size
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值