- 论坛徽章:
- 1
|
回复 #19 jiufei19 的帖子
自己再顶下。
这几天我又来来回回阅读了rfc2581,rfc2582,FF96,alexey kuznetsov的那篇文档,初步进行了如下总结,望大家指正
1、因重传超时定时器到时引发的分段丢失,于是就如同eexplorer描述的那样,发送方立即进入loss状态,所有从snd_una -> high_seq之间的包都会被认为是丢失了。然后tcp把cwnd设成1,使用slow start重发所有丢失的包。也就是说,假设S1 timeout了,TCP先发S1,收到ack后,cwnd加1,然后发送S2, S3。
>> 这里有必要说明下,我原来存疑的一个问题就是在重发S1后,是否应该立刻可以发送S2,查了上述若干文献,都没有看到明确说明,但是仔细想想,此时进入了慢启动阶段,如果重发分段不受慢启动控制,似乎有点别扭,因此感觉eexplorer的说明是正确的,在此表示感谢
2、因连续收到3个重复ACKs所引发的分段丢失,此时根据rfc2581可以明确看出,Reno算法中(Stevens 在tcpip协议详解中21.6、21.7及21.8中描述)发送方在进行重发丢失分段后,实际上进入到拥塞避免阶段,此时并不一定要等待重发分段的ACK到达后才能发送新分段,是否可以即刻发送新分段仅受当前cwnd状态变量的限制,如果可以就发送,不行就必须等待额外的重复ACK的到来以增加cwnd直到又可以发送新分段为止(Stevens给出的21.8节例子恰恰是不允许发送,而必须等待cwnd增加到某个程度时的例子)
3、对于Reno算法,快速恢复阶段终止于只要某个ACK有对新数据的确认,而NewReno算法的快速恢复阶段一直保持到一个窗口内所有丢失分段都被重发并成功确认为止
4、Reno和NewReno算法都必然固有一个性能低下的问题,即一个窗口内有多个分段丢失的话,则根据我在20楼发的帖子可以看出,在一个RTT内只能有一个丢失分段被重传,所以效率较低(FF96等几个文献中所给出的该问题的原因,说实话,我没有很好地弄懂,望有人能指点下,这里我是根据这几个文献的描述大概揣摩出的,不晓得正确否)。当然如果有SACK后,则发方就知道哪些该重发,哪些不重发,于是重发效率就高了
5、在rfc2582中有如下一段话
----------------------------------
This NewReno modification differs from the implementation in [RFC2581] only in the introduction of the variable "recover" in step 1, and in the response to a partial or new acknowledgement in step 5.
...
ssthresh = max (FlightSize / 2, 2*MSS) (1)
【Record】the highest sequence number transmitted in the variable "recover".
----------------------------------
显然这个recover变量似乎就是linux中的tp->high_seq,代表发送方曾经发出的最大序号,而不是曾经发出的最大序号+1(snd.nxt),eexplorer在我的另外一篇帖子“Linux TCP协议栈处理函数tcp_sacktag_write_queue的分析问题”中认为就是snd.nxt,似乎值得商榷,eexplorer的原文摘录如下:
high_seq是tcp进入recovery state的时候的snd_nxt,以你举的例子为例,当收到连续3个duplicated ack后,tcp进入recovery state,这时已经发送了S5,那么这时的snd_nxt就是s6,high_seq也就是s6了。 |
|