TCP之拥塞控制

流量控制

如果发送方发送数据过快,那么接收方来不及接收,就会丢弃数据。为了避免分组丢失,需要进行流量控制,避免发送方的数据将接收方淹没。

实现

流量控制的实现是基于滑动窗口。接收方在发送给发送方的ACK中包含了自己的接收窗口大小,当接收窗口为0时,发送方将暂停发送数据。

例如下图中,在连接建立时,发送方B告知接收方A,它的接收窗口大小为400,那么发送方发送的数据不能超过这个大小。

Nagle算法

此算法主要是为了避免发送方频繁地向接收方发送较小的数据。如果发送方发送1字节的数据,每次发送的IP包大小为20 + 20 + 1,分别是IP头部 + TCP头部 + 数据,这样会造成带宽的浪费。

Nagle算法流程

  1. 发送方先发送1字节的数据
  2. 对于后面需要发送的数据,发送方会先缓存起来
  3. 当收到前一个发送数据的ACK时,才发送缓存的数据
  4. 若缓存的数据达到发送窗口的一半或者达到报文段的最大长度,也会发送数据

愚笨窗口综合症(silly window syndrome)

此算法主要是为了避免接收方频繁地向发送方发送ACK。当接收方的接收窗口满时,应用层每次从接收窗口读取1字节的数据,此时接口方立即向发送方发送ACK,告知发送方此时接收窗口为1,可以发送1字节的数据,那么发送方不得不发送1字节的数据,此时接收窗口又满了。如此反复使得传输效率低下

为了避免上述情况,接收方需要等待一段时间,当接收窗口有一半空闲的大小或者可以容纳一个最长的报文,则发送ACK到发送方,告知其接收窗口大小。

拥塞控制

路由器有一个数据队列,用来保存接收到的数据,当路由器接收到太多的数据,导致队列满了,就会无条件地丢弃新到来的数据。此时上层的TCP认为数据在网络中丢失了,又会重传这些数据,而路由器又会丢弃这些重传的数据,如此反复,导致网络性能下降。因此TCP需要进行拥塞控制

流量控制与拥塞控制的区别

拥塞控制是防止过多的数据涌入到网络中,它是一个全局性的过程,它涉及到所有主机,所有的路由器。

流量控制针对的是点对点之间的通信,它主要是防止接收方被发送方的数据淹没,即控制发送方发送数据的速率,使得接收方来得及接收。

拥塞算法

TCP通过拥塞窗口(cwnd)来控制拥塞,发送方可以发送的数据大小为,其中rwnd表示接收窗口

min(cwnd,rwnd)

在不同的阶段,cwnd具有不同的计算方式

慢启动阶段(Slow Start Phase)

在慢启动阶段,初始时,cwnd被设置为1,但是每经过一个RTT,cwnd变成指数增长,直到cwnd>=阈值(ssthresh)

Initially cwnd = 1
After 1 RTT, cwnd = 2^(1) = 2
2 RTT, cwnd = 2^(2) = 4
3 RTT, cwnd = 2^(3) = 8

拥塞避免阶段(Congestion Avoidance Phase)

当cwnd>=ssthresh,进入拥塞避免阶段。因为此时网络拥塞的可能性变大,cwnd不在指数增长,而变成线性增长,每经过一个RTT,cwnd = cwnd + 1

Initially cwnd = i
After 1 RTT, cwnd = i+1
2 RTT, cwnd = i+2
3 RTT, cwnd = i+3

拥塞检测阶段(Congestion Detection Phase)

当网络出现拥塞时,TCP需要判断是什么情况导致了拥塞,对于不同的情况,cwnd的计算不同。

(1)由于超时而导致的重传

1. ssthresh变成cwnd的一半,ssthresh=cwnd/2
2. cwnd重置为1
3. 进入到慢启动阶段

如上图所示,当cwnd=24时,发生超时,ssthresh被重置为cwnd的一半,即ssthresh=cwnd/2=12.同时cwnd被重置为1,再次进入慢启动阶段

(2) 连续收到3个重复的ACK(数据丢失了)

1. ssthresh变成cwnd的一半,ssthresh=cwnd/2
2. cwnd重置为ssthresh
3. 进入到拥塞避免阶段

如上图,当收到3个重复的ACK,ssthresh被重置为cwnd的一半,即ssthresh=cwnd/2=12,同时cwnd被重置为ssthresh,即12,同时开始进入拥塞检测阶段,cwnd开始线性增长。

参考文献


Reprint please specify: wbl TCP之拥塞控制

Previous
分布式锁 分布式锁
分布式锁的应用场景为什么需要用到分布式锁呢?在讨论这个问题之前,我们先看下一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。 由于系
2019-08-11
Next
MySQL Explain详解 MySQL Explain详解
简介explain命令可以对Select语句进行分析,并输出 SELECT 执行的详细信息, 以供开发人员针对性优化. explain的用法,只需要在Select语句之前加入explain即可 explain SELECT * from u
2019-07-27