zoukankan      html  css  js  c++  java
  • tcpip详解笔记(19) persist定时器

    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

  • 相关阅读:
    I方法怎么不能获取多选框的数据
    html checkbox多选框语法与结构
    你真的了解new function(){} 和 function(){}()吗?
    适配方案(六)适配的基础知识之页面中那些内容需要适配
    适配方案(五)适配的基础知识之设备像素比 dpr 与 1px 物理像素
    适配方案(四)适配的基础知识之单位、分辨率、viewport
    onreadystatechange和onload区别分析以及如何判断script是否加载状态
    WebFont技术使用之如何在app中使用自定义字体
    服务端相关知识学习(六)Zookeeper client
    服务端相关知识学习(五)之Zookeeper leader选举
  • 原文地址:https://www.cnblogs.com/feisky/p/2735738.html
Copyright © 2011-2022 走看看