在 TCP 的慢启动和拥塞控制中, 当发生拥塞时, TCP 进行慢启动, 当慢启动进行到一定阀值后进行拥塞避免. 正如 "TCP/IP 协议详解" 中提到的, "慢启动" 这个术语并不准确, 拥塞窗口在慢启动期间以指数速率增长. 在拥塞避免算法进行时, 拥塞窗口以线性速率增长, 每次加 1.
这两个算法可以用编程语言来实现:
using System; class Test { static int cwnd1 = 1; static int cwnd2 = 1; static int ssthresh = 64; public static void Main(){ int step = 20; for(int i=0; i<step; i++){ grow1(); grow2(); Console.WriteLine("{0,8}\t{1,8}", cwnd1, cwnd2); } } // 完全指数增长. static void grow1(){ int num = cwnd1; for(int n=0; n<num; n++){ cwnd1 += 1; } } // 先指数增长, 然后加性增长. static void grow2(){ int wnd = cwnd2; int ssthresh_var = 0; for(int n=0; n<wnd; n++){ if(cwnd2 < ssthresh){ cwnd2 += 1; }else{ if (++ssthresh_var == wnd) { ssthresh_var = 0; cwnd2 += 1; } } } } }
TCP/IP 源码的一个疑问:
TCP/IP 详解 1 这样描述: 设置拥塞窗口 cwnd 为1, 发送 1 个报文段, 收到一个 ACK 后, cwnd 加 1, 然后发送 2 个, 收到 2 个 ACK 后, cwnd 加 2, 然后发送 4 个...
这确实是指数增长, 但是, 因为延时 ACK 的存在, 发送的2个报文段可能只收到 1 个 ACK, 所以 cwnd 只增加 1 而不是增加 2. 在延时 ACK 影响的范围内, 这是线性增长.
希望熟悉 TCP/IP 的朋友帮忙解惑, 十分感谢!