本文共 1732 字,大约阅读时间需要 5 分钟。
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++;
}
}