现在的位置: 首页 > 综合 > 正文

TCP:浅析拥塞控制窗口、慢启动、拥塞避免在linux内核中的实现

2014年01月05日 ⁄ 综合 ⁄ 共 2053字 ⁄ 字号 评论关闭

1、TCP的拥塞控制窗口

TCP的拥塞控制窗口是对每一个字节进行编号,在linux内核的实现中发送窗口snd_cwnd和接收窗口rcv_cwnd都是定义为MSS的个数,拥塞控制算法进行决定那些数据包可以发送,按照在[snd_una,sed_una+snd_cwnd]范围内的数据包发送,

相关的定义如下:

u32  snd_una; /* First byte we want an ack for      */

u32  snd_nxt;  /* Next sequence we send                */

u32  rcv_wnd; /* Current receiver window              */

u32  snd_nxt;  /* Next sequence we send                */

u32  rcv_nxt;   /* What we want to receive next */

发送窗口和接收窗口的更新

//改图来至网络

2、linux内核中拥塞控制算法:典型的慢启动和拥塞避免的算法分析

拥塞控制算法的慢启动的代码如下:

void tcp_slow_start(struct tcp_sock *tp)

{

         intcnt; /* increase in packets */

 

         /*RFC3465: ABC Slow start

          * Increase only after a full MSS of bytes isacked

          *

          * TCP sender SHOULD increase cwnd by thenumber of

          * previously unacknowledged bytes ACKed byeach incoming

          * acknowledgment, provided the increase is notmore than L

          */

         if(sysctl_tcp_abc && tp->bytes_acked < tp->mss_cache)

                   return;

 

         if(sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd >sysctl_tcp_max_ssthresh)

                   cnt= sysctl_tcp_max_ssthresh >> 1;      /*limited slow start */

         else

                   cnt= tp->snd_cwnd;                           /*exponential increase */

 

         /*RFC3465: ABC

          * We MAY increase by 2 if discovered delayedack

          */

         if(sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache)

                   cnt<<= 1;

         tp->bytes_acked= 0;

 

         tp->snd_cwnd_cnt+= cnt;

         while(tp->snd_cwnd_cnt >= tp->snd_cwnd) {

                   tp->snd_cwnd_cnt-= tp->snd_cwnd;

                   if(tp->snd_cwnd < tp->snd_cwnd_clamp)

                            tp->snd_cwnd++;

         }

}

 

发送方,在慢启动阶段每收到一个ACK,tp->snd_cwnd++,即窗口加一,在RTT时间内可以增加一倍,

而在拥塞避免阶段使用tcp_cong_avoid_ai()函数来进行线性增加窗口,没收到一个ACK就增加增加1/ tp->snd_cwnd,在RTT时间增加MSS

其中:变量snd_cwnd_cnt是一个很关键的变量,定义如下:

u32  snd_cwnd_cnt;         /* Linear increase counter                */

 

void tcp_cong_avoid_ai(struct tcp_sock *tp,u32 w)

{

         if(tp->snd_cwnd_cnt >= w) {

                   if(tp->snd_cwnd < tp->snd_cwnd_clamp)

                            tp->snd_cwnd++;

                   tp->snd_cwnd_cnt= 0;

         }else {

                   tp->snd_cwnd_cnt++;

         }

}

【上篇】
【下篇】

抱歉!评论已关闭.