feisky

云计算、虚拟化与Linux技术笔记
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

tcpip详解笔记(19) persist定时器

Posted on 2012-10-23 20:28  feisky  阅读(482)  评论(0编辑  收藏  举报

persist定时器

1. 使用persist定时器的原因

ACK的传输不可靠,TCP并不对ACK报文进行确认,TCP只确认哪些那些包含了数据的ACK报文段。

这样,如果一个ACK丢失了,就会因双方相互等待而导致连接终止:接收方等待接收数据(它已经通告了一个非0的窗口),发送方在等待允许它继续发生数据的窗口更新。

2. persist定时器:发送方使用一个persist定时器来定期的向接收方查询窗口是否增大,这些从发送方发出的报文段称为窗口探查。窗口探查包含一个字节的数据,即序号。这些探查每隔60s发送一次,直到窗口被打开或者连接被终止。

3. 糊涂窗口综合症

糊涂窗口综合症的产生

考虑以下两种情况:

(1)接收方的应用程序读取数据慢,一次只读1个字节

可以想见,很快,接收方的缓存被填满,于是回发窗口通告[window advtisement]说:已满,勿发.
接下来,应用程序慢吞吞的读入1byte,缓存空余出来一字节,兴高采烈的再次回发窗口通告说:一字节可用,快来填满我.
发送方接到通告,生成并传送数据部分只一字节的报文.
然后,如此重复.

很明显,这样不好,效率太低. 一般TCP报文头部大小最少也是20字节,结果只拖这么点数据过去,头部的处理(校验和的计算,流的序列号的读取,数据的提取),到IP数据报的封装及相应的解封 又要照行不误,实在效率忒也底下了.

(2)相应的是发送方的应用程序,产出数据慢,一次一字节,一字节一个报文,也会导致效率问题.

糊涂窗口综合症的防治

(1)接收方
a.对每一个到达的TCP报文回送ACK,但在窗口的空余增大到指定大小之前,我都不会报告窗口的大小,免得回送一个1byte,你就想也不想就发个报文过来.
b.或者,延迟ACK的发送.并不一定对每个TCP报文都回送ACK,而是每个报文到达后,稍等片刻.

Adventage:
1.减少传输流量.一个ACK可能对多个报文做出确认回复,不用一一回复啦.
2.Piggyback. 当接收方收到数据后需要回送数据时,可以在回送数据的TCP报文中捎带[piggyback] ACK确认,同样减少了网络流量.
3. 窗口通告[window advertizement]是在数据于缓冲区被读取后才发出的,这和对应的报文的到达时间有一定延后,而ACK的延迟发送就可能等待到窗口大小的改变,两者一起回发(又是piggyback?),同样减少了数据流量.

Disadventage:
1.报文重传时间是根据报文来回时间推测而来的.ACK延迟策略影响了对合理重传时间的判断,本来一秒钟就到了的,结果延迟设定的时间太夸张,用了十秒,这边的传送方就说那好吧,就15秒吧,15秒还不到我就算你报文丢失了,直接结果就是反应迟钝,正常的5秒钟就可以判定丢失的,偏要等到15秒,好难等啊...
2.另外,延迟时间太夸张了,最直接的结果就是发送方等啊等,没等到,干脆重传了(其实那报文早到了,没回送确认而已),这样添加了无谓的重传,增加网络负担.

Solve:
相应的解决方法简单得很,既然都是延迟时间太夸张导致的,我就把延迟时间设个上限呗,现在的建议是0.5秒.

(2)发送方
想象一下,为了避免传输小数据报,可以让TCP稍等一会儿,待到数据聚集多后,一起发送,嗯,想法不错,不过等多少时间呢?
0.5秒?50秒?
关键是TCP应对的对象是多种多样滴,可以是人,是打字快的人,是半小时打一个字的打字慢的人,是5M/S的文件传输.....
对人,0.5秒太短,对文件传输,时间又太长.故时间的选择是一个问题.

想一种自适应的策略出来.

1.对打字慢的人来讲,不应该强行奢望说每个报文都携带大量数据,不然应用程序延迟太大,聊QQ我打一行字不一定有20byte呢,结果你强行说100byte我再给你发,我不是很郁闷.所以这种情况理想下应该及时发送,相比人的慢速,网络的ACK是到的快的,所以但凡ACK到达,我就发送下一数据报,而不理睬是否报文数据达到一定大小(这样就没有提高传输效率一说了,不过程序嘛,当然用户体验第一啦,小牺牲一下效率也是值得滴).
2.对传输大户比如文件传输呢?
还发一个报文,乖乖等ACK然后再发下一个就太慢了吧,乖乖,我可是10M/S的速度写入啊,这时就应该藐视ACK,只要缓冲区数据写入填满了最大报文,就立刻发送,毫不等待(当然了,还是得遵循滑动窗口的限制吧,猜测,待确认).
而兼容以上两种情况的策略就诞生了:

1 . 对从应用程序收到的第一块数据,发送端的TCP直接将它发送出去,哪怕只有一个字节。
2 .此后,发送端的TCP就在输出缓存中积累数据,并等待:或者接收端的TCP发送出一个确认,或者数据已积累到可以装成一个最大的报文段。二者满足其一,发送端的TCP就可以发送这个报文段。
3.对剩下的传输,重复步骤2。这就是:如果收到了对报文段x的确认,或者数据已积累到可以装成一个最大的报文段,那么就发送下一个报文段(x + 1)。


参考:
《TCP/IP详解》
http://mmliu.iteye.com/blog/686658

无觅相关文章插件,快速提升流量