zoukankan      html  css  js  c++  java
  • TCP流量控制协议

    说明 本文仅供学习交流。转载请标明出处,欢迎转载!

    本文是下面文献相关内容的总结

    [1] 《TCP/IP具体解释 卷1:协议》
    [2] 《TCP/IP协议族 第4版》
    [3] 《计算机网络 第5版》

            TCP流量控制的目的是限制发送端的发送速率,使得接收方可以及时接收。

    TCP主要是通过滑动窗体来实现流量控制的。实际上,发送窗体的大小不仅受接收窗体rwnd的大小的限制,还受拥塞窗体cwnd窗体的限制,为了实现点到点的流量控制,本文如果拥塞窗体足够大(即网络链路比較流畅),仅考虑发送窗体swnd受接收窗体的限制。

           窗体由左臂和右臂组成。左臂右移称为关闭,右臂左移称为收缩,右臂右移称为打开

           发送窗体和接收窗体的移动操作

           接收窗体:当接收方收到发送方的很多其它的字节时(不包含反复的报文段),接收窗体关闭。当接收缓存中的字节被接收进程pull时,接收窗体打开,通常接收窗体不会发送收缩操作。

           发送窗体:发送窗体的关闭、收缩和打开受接收方的控制。当一个有效的确认时,发送窗体关闭;当接收方通告发送方同意的窗体大小能够更大时,发送窗体会打开。当接收方通告发送方同意的窗体大小更小时。发送窗体就收缩,可是TCP强烈不建议发送窗体收缩

           注意:TCP窗体的单位是字节。不是报文段。所以TCP窗体中,每一格相应1B。

           利用滑动窗体进行流量控制过程

            

           上图中,在发送端与接收端建立连接时,接收端告诉发送端当前接收窗体rwnd=400。所以发送端最多可以发送400B,如果每个报文段为100B。

    发送端连续发送4个报文段。各自是1-100,101-200,201-300,301-400,401-500。发送后数据段101-200在路上丢失了,其它几个报文都被接收了。并放入到接收缓存中,接收方便向发送方发送1-200报文段的ACK。并期望收到序号为201相应的报文段。同一时候设置接收窗体大小rwnd=300,发送端便重传序号201相应的报文段。当接收端收到该报文段后,并向发送端发送前500个报文的ACK,并期望收到序号为501的报文段,并设置接收窗体rwnd=100。发送端收到该ACK报文段后,便向接收端发送序号为501-600的报文段,接收端收到该报文段后,发送ACK报文段。并设置rwnd=0,意在通知发送端不要临时再发送数据段。

           糊涂窗体综合症

           当发送应用程序产生数据的速度非常慢,或接收应用程序消耗数据的速度非常慢,或者两者都有,都会使得发送数据的报文段非常小,使得网络效率非常低,这个问题称为糊涂窗体综合症SWS(silly window syndrome)。

          发送方产生的症状

            假设发送方应用程序产生数据的速度非常慢。比如一次仅仅产生1B,那么就有可能产生糊涂窗体综合症。解决办法是防止发送TCP一次仅仅发送1B。必须让发送TCP等待。并把数据收集成较大的数据块后再发送。

           发送TCP须要等待多长时间再发送呢?

            假设等待时间过长。则会延迟整个过程。

    假设等待时间过短,最后非常可能还是发送一个个小报文段。Nagle提出了一种解决办法,我们称之为Nagle算法,过程例如以下

            1.发送TCP把它从应用程序收到的第一块数据发送出去。哪怕仅仅有一个字节;

            2.在发送了第一个报文段后。发送TCP先把发送应用程序兴许到达的数据字节缓存起来。直到收到接收端发来的ACK,或者已积累了足够的数据。发送TCP就能够发送这个报文段了。

            注意:足够的数据指的是数据达到0.5*MSS(最大报文段长度的一半)或者发送窗体大小的一半时。

           接收方产生的症状

            假设接收端应用程序pull速度非常慢,比如一次仅仅消耗1B的数据。若TCP接收方的缓存已满,而应用程序一次仅仅能从接收缓存中读取1B,然后向发送方发送ACK。并把窗体设置为1B(由于从接收缓存中取出了1B),但发送方的缓存中有非常多数据。这样发送方有仅仅能一次发送1B,接收方发回确认,仍然将窗体设置为1B,这样进行下去。网络的效率非常低,此时能够採取两种解决方法:

           方法1:採用Clark解决方法。该方法是:接收端仅仅要有数据到达就向发送端发送零值窗体ACK报文段。直到(1)缓存中有足够大的空间能够放入1MSS报文段,或者(2)至少有一半的缓存空间空暇。仅仅要出现这两种情况之中的一个,接收端就向发送端发送非零值窗体ACK报文

            方法2:推迟确认。当报文段到达时并不马上发送确认,接收方在对收到的报文段进行确认之前一直等待,直至接收缓存有足够的空间为止。

    推迟发送确认防止了发送TCP滑动它的窗体。

    推迟确认的另外一个长处:降低了网络的通信量;相应的缺点是:假设推迟的时间比較长,会使得发送方以为发送的报文丢失,而产生不必要的重传。

           总之。发送方和接收方能够配合解决该问题。整体的思想是:发送方不发送非常小的报文段的同一时候,接收方也不要在缓存刚刚有了一点小空间就急慌忙这个非常小的窗体大小的信息通知发件人。

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    iOS中Zbar二维码扫描的使用
    SOJ 1135. 飞跃原野
    SOJ 1048.Inverso
    SOJ 1219. 新红黑树
    SOJ 1171. The Game of Efil
    SOJ 1180. Pasting Strings
    1215. 脱离地牢
    1317. Sudoku
    SOJ 1119. Factstone Benchmark
    soj 1099. Packing Passengers
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4737083.html
Copyright © 2011-2022 走看看