• Linux网络编程系列-TCP传输控制


    滑动窗口(sliding window)

    滑动窗口是用于流量控制的,发送端根据接收端的处理能力发送数据,不至于造成过多的丢包。 是发送方和接收方间的协调,对方的接收窗口大小就是自己的发送窗口大小。
    在TCP头中有一个字段window,这个字段就是接收端告诉发送端自己还有多少缓冲区可以接收数据。发送端根据这个字段的值来发送数据,当值为0时就停止发送。
    发送端和接收端各自维护着一个窗口,发送的滑动窗口控制可以发送的数据大小,接收端的窗口控制可以接收数据的大小。
    发送端的窗口控制
    发送端:LastByteAcked指向已经被成功接收的位置,LastByteSent指向最后已发送出去的位置,usable window表示发送端还可以发送的数据大小。如上图,发送端还有5个单位数据还未被ack,还可以再发送7个单位的数据。

    接收端的窗口控制
    接收端:LastByteExpected指向接收端收到的连续包的最后一个位置,LastByteRcvd指向收到的包的最后一个位置,waited come表示期望收到的包序列,waited read表示在缓冲区中还未读走的数据,usable window表示缓冲区还能接受的大小。如上图,缓冲区还能接受7个单位的数据,就会把7赋值给tcp头中的window字段。

    发送端当收到window为0时,就停止发送数据,会陆续发送3次ZWP(zero window probe)询问接收端是否有可用窗口,接收端会回复可用窗口,如果3次都为0,发送端可能中断链接。

    拥塞控制

    滑动窗口用于流量控制,避免发送超过接收端处理能力的数据,导致数据丢失,是两端之间的协调。
    拥塞控制是TCP用于发送端和网络情况间的协调,和慢启动一起避免恶化网络状况。根据网络延时情况,确定可发送窗口大小。这就抽象出一个拥塞窗口(congestion window)的概念,其最大值是发送窗口大小。
    TCP有四个算法来动态调节拥塞窗口(cwnd)大小:

    • 慢启动
      连接建立时,cwnd=1
      cwnd线性上升,每收到一个ACK,cwnd++
      cwnd指数上升,每过一个RTT(round trip time),cwnd = cwnd * 2

    • 拥塞避免
      当cwnd>=ssthresh(slow start threshold),进入拥塞避免,cwnd的增加算法改成如下:
      每收到一个ack,cwnd=cwnd + 1/cwnd,基本不增加
      每过一个RTT,cwnd=cwnd + 1,在一个往返时间内最多为 cwnd增加 1 个报文段

    • 拥塞发生(超时RTO,丢包-重复收到同一个包的ACK)
      ssthresh = cwnd/2
      cwnd = 1,发送端基本不发送数据了。开始了慢启动的过程。

    • 快速恢复
      TCP为保证数据达到有两种重传算法,超时重传和快速重传。超时重传是等待RTT时间没收到ack,则重传;快速重传是接收端配合,接收端每收到一个tcp segment,返回的都是收到的连续序列的下一个序号,发送端收到3次同样的序号就进行重传。
      快速恢复通常和快速重传一起使用,如果接收端还能收到重复的ACK,说明收发两端还有数据流动。所以没必要反映那么强烈,不需要把cwnd降为1,可以缓和点减少流量,不进入慢启动。这是快速恢复的思想。
      1) 当收到第 3 个重复的 ACK时(认为拥塞发生),将 ssthresh设置为当前拥塞窗口 cwnd的一半。重传丢失的报文段。设置cwnd为ssthresh加上3倍的报文段大小。
      2) 每次收到另一个重复的 ACK时, cwnd增加 1个报文段大小并发送 1 个分组(如果新的cwnd允许发送)。
      3) 当下一个确认新数据的ACK到达时,设置 cwnd为ssthresh(在第1步中设置的值)。这个ACK应该是在进行重传后的一个往返时间内对步骤 1 中重传的确认。另外,这个ACK也应该是对丢失的分组和收到的第 1 个重复的 ACK之间的所有中间报文段的确认。这一步采用的是拥塞避免,因为当分组丢失时我们将当前的速率减半。
      总结下,收到重复的ack时,窗口和阈值减半,进入拥塞避免,试探性的重发丢失的报文段,直到无窗口可用或者拥塞消除。

    注:网络实际传输受slidingwnd和cwnd控制,TCP能传输的最大数据 = MIN(slidingwnd, cwnd)
    参考TCP的那些事儿(下)http://coolshell.cn/articles/11609.html

  • 相关阅读:
    dll反编译工具(ILSpy)的使用
    织梦CMS进入自定义表单界面查看数据
    SQL -注释方法
    SQL之CASE WHEN用法详解
    Windows Installer Clean Up 软件卸载工具下载
    【精华合辑】金蝶云BOS资料合辑
    报表二次开发添加自定义字段的指导方案
    怎样选购笔记本内存条?
    SQL Server 2008修改sa密码的详细方法
    VS 2015 2019注册码
  • 原文地址:https://www.cnblogs.com/whuqin/p/4981959.html
Copyright © 2020-2023  润新知