网络 -- TCP流量控制拥塞控制

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络 -- TCP流量控制拥塞控制相关的知识,希望对你有一定的参考价值。

文章目录

流量控制:点对点关系;发送方与接收方的通信, 主要是接收方能力较差时引起问题.

当发送速度 >接收的速度, 接收方就丢包. 丢包之后,发送方就会重传,而重传后的数据包又被丢弃.

拥塞控制:全局关系到整个网络; 主要是发送与接收端 之间的中间节点问题(路由器,交换机,集线器这些的问题);

网络拥堵,发送方无法收到ACK确认,就重传,而重传之后会使得网络再次拥堵.


1.流量控制部分


发送/接收缓存区:位于Socket Library 层

这里应用程序与发送/接收的缓冲区交互,而不是直接调用tcp/ip协议栈;
也就是非阻塞式编程.

  • 应用程序调用write时,数据只是写入本机的发送缓冲区,其中并没有立即发到网络上.
  • 应用程序调用read时,并不会等待网络上的数据到来,只是读取本地接收缓冲区的数据,读取不到就直接返回.


需要注意的是:

  • 客户端/服务器之间的每条TCP连接上,都有一个发送缓冲区,一个接收缓冲区;也就是TCP的连接数越多,消耗内存越多;
  • 查看缓冲区大小: net.ipv4.tcp_wmen = 4096,16384,4194304; min(4K)、default(16K)、max.
  • 可设置发送/接收缓冲区的大,当然操作系统也可自动地调节.

1.1 滑动窗口


发送窗口位于发送缓冲区, 接收窗口位于接收缓冲区

第一种案例:客户端写, 服务端读数据.

第二种案例:服务器写数据,客户端读数据.


发送窗口的结构

  • 发送窗口: 即允许发出的数据范围,没有收到确认的ACK之前,允许发送的最大数据量范围;
  • 发送窗口收缩到0后,不能再发送数据;
  • 每次收到1次ACK,发送窗口就会向右滑动,P2变短,P3变长

接收窗口结构

  • 接收窗口:即允许接收的数据范围.
  • 数据每秒被应用程序接收读取后,该窗口就会向右滑动一次,然后删除窗口左边的部分.
  • 若应用程序过慢,数据就不能被及时读取,最终堵塞窗口,将无法继续接收数据,收到新数据也会被丢弃.


1.2 流量控制


所谓流量控制就是发送方与接收方动态调整自己的窗口大小范围.


当窗口收缩到0时,可能出现死锁!!!

  • 发送方的窗口收缩到0时,那么此时发送方无法和接收方进行数据通信,需要等待接收方发来确认ACK;确定新的发送窗口大小.
  • 若此时接收方发来的确认ACK丢失,那么发送方与接收方就会相互等待,出现死锁.
  • 如何解决该场景? --> 当发送方的窗口收缩到0之后,发送方就启动一个定时器,定期为接收方发送探测报文, 检测窗口是否扩大了,若检测时的窗口一直是0,那么就可以直接关闭连接.

1.3 发送方的延迟Nagle算法


IP网络层在设计时就是为了提升网络的吞吐量能力,提升传输效率,所以不希望大量的极小分段数据包在网络中传输,耗费网络带宽速度.

小包:数据大小小于MSS的包;
极小包: 数据大小 小于 (TCP头部+IP头部)

尽量避免出现过多的小数据包.

  • 可让发送方延迟发出数据,根据Nagle算法 积累一批数据包后一次性发送.
  • 可以让接收方延迟发出确认的ACK编号,积累一批后进行发送.

Nagle算法默认开启,当然也可以设置TCP的属性TCP_NODELAY来禁用它;

该延迟算法的核心原则为:任意时刻仅允许有一个未被ACK确认的小数据包存在.
允许发送的条件

  • 若数据包 >= MSS[TCP的最大报文段长度],可以发送.
  • 包含有FIN(关闭序列编号),允许发送;
  • 设置了关闭Nagle算法的属性TCP_NODELAY,允许发送;
  • 发生超时[默认200ms],也允许发送.

注意: Nagle算法可能引发网络延迟,一般是禁用的,上层应用此时就可根据场景来控制数据的发送时机.


延迟ACK: 接收方收到一定量的数据包之后,再返回ACK确认.

普遍默认延迟200ms, 在接收方放一个定时器,定时查看200ms内是否有新的ACK需要发送,
而这个延迟时间实际小于等于200ms, 案例:在160ms时收到了数据包,且接收处理完毕,那么再过40ms后即可返回该ACK;


2. 拥塞控制


注意:发送方只是猜测网络拥塞;而不是绝对确定.
当发送方发出一个数据包,长时间收到不到ACK ,那么可能是网络拥塞/接收方的接收能力问题.

由于这种不确定性,所以在发送方又设定了拥塞窗口, 反映网络的堵塞程度.

发送窗口 = Min(拥塞窗口/接收窗口)

发送方根据接收方回复ACK的快慢速度,可以动态地调节拥塞窗口的范围;也就是调节了发送窗口的范围.
案例:

  • 开启,拥塞窗口较小,只要回复ACK的时候不超时,那么窗口就可以调大,收到一次ACK回复,就调大一次;
  • 指数级增大 --> 线性增大.
  • 当ACK超时,即可确认网络阻塞,可以将窗口缩小.

慢开始策略: 先进行指数级增长窗口大小.

拥塞避免: 由线性增长调整减小窗口大小.


对于网络拥塞的判断实际还要取决于ACK的超时时间,这个时间需要自适应调整.

那么按照惯性的思路,这个超时时间就按照RTT时间来设定; 超时时间大于RTT时间一点即可.

RTT时间:即表示从发送端发送数据开始-->发送端收到来自接收端的确认这个过程的往返时间

可是,RTT并不是一个固定的值,它是一个序列;
案例:

连续发数据包1,数据包2, 收到了ACK=2, 此过程时间为RTT1;
再发数据包3,收到ACK=3, 此过程时间为RTT2;
连续发数据包4,数据包5,数据包6,收到的ACK=6,此过程时间为RTT3.
要使用哪个RTT时间作为超时时间的标准呢?

可用时间序列预测中的EWMA[指数加权平均移动算法]
可以考虑使用历史数据序列值,预测目前的RTT值, 可调整超时时间;
RTTs(新) = (1-a) * RTTs(老) + a*RTT(最新值)

注:RTT:样本值,RTTs:预测值,a:常数[默认0.125]


快重传策略
快重传的设定:
(1)接收方要是收到失序的数据报文,就立即恢复ACK确认,不需要延迟ACK;

案例:接收方先收到数据包1和数据包2,回复ACK=3; 在此基础上,后面又收到数据包4和数据包5,但是没收到数据包3,即 数据包3已经丢包,那么就得发送ACK=3,即使ACK=3在上次已确认发送,这里仍然重复ACK回复.

(2)发送方连续收到三个重复的ACK,立即重传没有收到的数据报文,即使还没到超时时间.

未使用快恢复策略时;

采用快恢复策略之后;

没有慢开始的指数级别增长,发生网络拥塞之后[即收到重复的ACK确认编号]后;从中间开始,线性增长.


以上是关于网络 -- TCP流量控制拥塞控制的主要内容,如果未能解决你的问题,请参考以下文章

TCP的拥塞控制

TCP拥塞控制-慢启动拥塞避免快重传快启动

网络 -- TCP流量控制拥塞控制

网络 -- TCP流量控制拥塞控制

计算机网络之TCP拥塞控制

计算机网络概述 传输层 TCP拥塞控制