美文网首页
TCP流量控制

TCP流量控制

作者: 进击的蚂蚁zzzliu | 来源:发表于2021-03-24 16:31 被阅读0次

一、Socket缓冲区

1. 发送缓冲区
发送缓冲区.png
发送缓冲区分为4部分,按照顺序排列
已发送已确认:已经发送,并且收到客户端ACK;
已发送未确认:已经发送,等待ACK;
可发送未发送:已经准备好了,马上就可以发送;
不可发送:尚未准备好,不能发送;
2. 接收缓冲区
接收缓冲区.png
接收缓冲区也分为4部分,按顺序排列,但是中间可能会有空的:
应用层已读取:应用层已经读取;
已确认未读取:已经发送ACK,等待应用层读取,应用层如果处理的慢,这部分会变大;
等待接收和未确认:已经接收尚未发送ACK的以及按顺序中间尚未收到等待接收的部分;
不能接收:处理速度等原因暂时无法接收的部分;

二、超时机制

服务端对每一个已发送的包都设一个定时器,超过了一定的时间,就重新尝试,这个时间不宜过短,时间必须大于往返时间 RTT,否则会引起不必要的重传。也不宜过长,这样超时时间变长,访问就变慢了。

自适应重传策略:估计往返时间,需要 TCP 通过采样 RTT 的时间,然后进行加权平均,算出一个值,而且这个值还是要不断变化的,因为网络状况不断地变化。除了采样 RTT,还要采样 RTT 的波动范围,计算出一个估计的超时时间。如果一个包经历过一次超时重传后,下一次超时时间加倍,两次超时,就说明网络环境差,不宜频繁反复发送。

快速重传策略:当接收方收到一个序号大于下一个所期望的报文段时,就会检测到数据流中的一个间隔,于是它就会发送冗余的 ACK,仍然 ACK 的是期望接收的报文段。而当客户端收到三个冗余的 ACK 后,就会在定时器过期之前,重传丢失的报文段。
例如:上面接收缓冲区中10已经收到11未收到,当收到12时回复10的ACK表示下一个要11,同理收到13时也回复10的ACK,当服务端收到3个10的重复ACK就知道11丢了,于是不等超时直接重发11。

SACK策略:在 TCP 头里加一个 SACK 的东西,可以将缓存的地图发送给发送方。
例如可以发送 ACK10、SACK12、SACK13,有了地图,发送方一下子就能看出来是 11 丢了。

三、流量控制

滑动窗口:窗口大小指的是不需要等待确认应答包而可以继续发送数据包的最大值;ACK包中同时会携带一个窗口的大小,表示客户端当前可接收的大小,用于让发送方动态调整窗口大小;
例如上图发送缓冲区中假设当前窗口大小为9(3 - 11),当收到4的ACK时窗口右移一位为 4 - 12,这时12就可以发送了;这时候如果发送端发送过猛,会将第三部分的 10、11、12全部发送完毕,之后就停止发送了,未发送可发送部分为 0。这时当5的ACK到达时窗口才能继续右移,继续发送。

当客户端程序处理缓慢时,极端情况下等待接收和未确认部分全部变为已确认未读取,这时客户端回复ACK时告诉发送方窗口为0,发送方停止发送。如果这样的话,发送方会定时发送窗口探测数据包,看是否有机会调整窗口的大小。当接收方比较慢的时候,要防止低能窗口综合征,别空出一个字节来就赶快告诉发送方,然后马上又填满了,可以当窗口太小的时候,不更新窗口,直到达到一定大小,或者缓冲区一半为空,才更新窗口。

四、拥塞控制

拥塞控制也是通过窗口的大小来控制的,前面的滑动窗口 rwnd 是怕发送方把接收方缓存塞满,而拥塞窗口 cwnd,是怕把网络塞满。

慢启动

如果我们通过漏斗往瓶子里灌水,我们就知道,不能一桶水一下子倒进去,肯定会溅出来,要一开始慢慢的倒,然后发现总能够倒进去,就可以越倒越快。这叫作慢启动。

传统算法

一条 TCP 连接开始,cwnd 设置为一个报文段,一次只能发送一个;当收到这一个确认的时候,cwnd 加一,于是一次能够发送两个;当这两个的确认到来的时候,每个确认 cwnd 加一,两个确认 cwnd 加二,于是一次能够发送四个;当这四个的确认到来的时候,每个确认 cwnd 加一,四个确认 cwnd 加四,于是一次能够发送八个。可以看出这是指数性的增长。

涨到什么时候是个头呢?有一个值 ssthresh 为 65535 个字节,当超过这个值的时候,就要小心一点了,不能倒这么快了,可能快满了,再慢下来。每收到一个确认后,cwnd 增加 1/cwnd,我们接着上面的过程来,一次发送八个,当八个确认到来的时候,每个确认增加 1/8,八个确认一共 cwnd 增加 1,于是一次能够发送九个,变成了线性增长。

但是线性增长还是增长,还是越来越多,直到有一天,水满则溢,出现了拥塞,这时候一般就会一下子降低倒水的速度,等待溢出的水慢慢渗下去。拥塞的一种表现形式是丢包,需要超时重传,这个时候,将 sshresh 设为 cwnd/2,将 cwnd 设为 1,重新开始慢启动。但是这种方式太激进了,将一个高速的传输速度一下子停了下来,会造成网络卡顿。

快速重传

当接收端发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发送端就会快速地重传,不必等待超时再重传。TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,cwnd 减半为 cwnd/2,然后 sshthresh = cwnd,当三个包返回的时候,cwnd = sshthresh + 3,也就是没有一夜回到解放前,而是还在比较高的值,呈线性增长。


image.png
BBR

TCP BBR 拥塞算法。它企图找到一个平衡点,就是通过不断地加快发送速度,将管道填满,但是不要填满中间设备的缓存,因为这样时延会增加,在这个平衡点可以很好的达到高带宽和低时延的平衡。

----------over---------

  • 参考《TCP协议(下):西行必定多妖孽,恒心智慧消磨难》- 刘超

相关文章

网友评论

      本文标题:TCP流量控制

      本文链接:https://www.haomeiwen.com/subject/jwchhltx.html