Linux网络编程4-经典TCP拥塞控制算法解析-2
前言
在本系列博客中,我们使用的是 Ubuntu20.04版本 ,使用的虚拟机为Oralce VM VirtualBox
写在前面
在本标题下面,我们会为大家分享最为经典的3种TCP拥塞控制算法,分别是reno,cubic,vegas。这里我们介绍bic和cubic拥塞控制机制。
bic与cubic不得不说的那些事
值得注意的一些事
其实有很多人在接触这bic和cubic的时候,总是认为这两个算法是一个以另一个为基础的,比如在bic的基础上加上了一个简称为cu的机制或算法对bic进行优化升级,于是出现了cubic,包括我自己在一开始的时候也进入了这样的一个误区,经过后面的了解我才知道这是一个大家常犯的错误。bic是英文Binary Increase Congestion的缩写,而cubic就是英文平方,两个看似相似的算法却并没有我们想象之中的关联。
bic
我们前面提到了bic的全称,这里我们再次强调一下,Binary Increase Congestion,见文知意,我们不难从他的名字中看出一些端倪,二元增加,这个概念可以相对于reno来进行理解,reno中的拥塞避免阶段是通过线性增加或者所谓的加性增来探测网络并一点点增加发送窗口直到出现拥塞,而bic是通过一种更为快捷的方式对网络进行试探。
与reno相同的是,当发送窗口小于我们设定的阈值时,仍然使用慢启动算法迅速将窗口增长至慢启动阈值ssthresh
结合代码
这里我们结合Linux内核版本为2.6.0中的文件tcp_bic.c中的部分代码来看一下
static void bictcp_cong_avoid(struct sock *sk, u32 ack,
u32 seq_rtt, u32 in_flight, int data_acked)
{
struct tcp_sock *tp = tcp_sk(sk);
struct bictcp *ca = inet_csk_ca(sk);
if (!tcp_is_cwnd_limited(sk, in_flight))
return;
if (tp->snd_cwnd <= tp->snd_ssthresh)
tcp_slow_start(tp);
else {
bictcp_update(ca, tp->snd_cwnd);
/* In dangerous area, increase slowly.
* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
*/
if (tp->snd_cwnd_cnt >= ca->cnt) {
if (tp->snd_cwnd < tp->snd_cwnd_clamp)
tp->snd_cwnd++;