这几天一直在看TCP/IP详解->TCP超时重传这一章,这章的内容可以毫不夸张的说是TCP的难点,。本章重点讲了Van.Jacobson的慢启动,拥塞避免算法,快速重传算法,快速恢复算法,在讲解中stevens重点关注了在传输中,cwnd(拥塞窗口),ssthresh(慢启动极限)的变化。现在重点描述一下在以下状态这两个值的变化:
发送SYN超时->SYN重传->慢启动->拥塞避免算法->数据分组丢失->重复ACK->重传丢失数据分组->重复ACK->发送新的数据分组->重发数据ACK->->
(1)在发送SYN期间超时,cwnd设置一个报文段(256字节),ssthresh设置最小取值2D(两个报文段512字节),SYN重传成功后不会更新cwnd,ssthresh做任何修改,发送方将等待新的ACK发回;
(2)发送方进入慢启动状态后ssthresh不会变化,每次收到ACK时候cwnd=cwnd + 一个报文大小,说明在慢启动期间cwnd是成指数级增长的;
(3)当cwnd超过了ssthresh时进入拥塞避免算法状态,此刻cwnd增长速率减小cwd = cwnd + segsize*segsize/cwnd + 1/cwnd,但是实际上早期的BSD并没有按照这个算法去实现,而是错误按照cwd = cwnd + segsize*segsize/cwnd + segsize/8去实现;
(4)在传输数据的时候出现数据分组丢失时,一旦被接受方发现,接受方将一直发送重复ACK,此刻cwnd,ssthresh不变化(因为有可能是TCP传送序号失序),当接受方发现3个重复ACK的时候,接受方就立即发送丢失数据分组,就是是所谓的快速重传;
(5)重传数据分组后,ssthresh变化为当前cwnd的一半(四舍五入去整),而cwnd设置为当前变化后的ssthresh + 3*报文段,这里乘3的原因是快速重传算法传三次;
(6)然后继续接受重复ACK,在此期间发送方运行发送数据但必须cwnd的容量大于通告窗口缓存里的容量才可传入新的数据分组,这就是所谓的快速恢复,cwnd在这个阶段也是按照报文段个数增长(与慢启动期间相同);
(7)最后发送方终于回复了重传数据包的ACK后,cwnd被设置成ssthresh的值,ssthresh不变,此时由于cwnd小于等于ssthresh,因此cwnd增加一个报文段大小,此时cwnd大于ssthresh接收方又进入拥塞避免状态.
写得有点乱,详细请看TCP/IP协议详解 卷一 p239,重点看那三张图,画得很直观,很清晰,。