TCP流量控制与拥塞控制

TCP是一个提供可靠传输,按序递交数据,兼顾传输效率的协议。

TCP是如何保证可靠的?TCP在可靠的前提下又是如何保证传输效率的?


1. TCP如何实现可靠:

CRC + SN + ACK + ARQ + 重复丢弃 + 重排序

1.1 CRC + ARQ:(针对数据出错的情况)

  数据在底层网络中传输时可能出现内容比特级差错(底层通信媒介可能会 改写 或 删除 比特),为保证数据正确,接收端需要对数据进行校验,检测收到的数据是否与初始发送的数据内容一致。
  TCP会对数据包的 头、体 分别进行 CRC校验,如果出现差错,则将数据丢弃,发送端在超时未收到确认报文ACK后会发起重传(ARQ)。

1.2 SN + ACK + ARQ:(针对数据丢失 或 ACK丢失的情况)

  数据可能在底层网络丢失,发送端会为发出的每个数据分组打上SN,并起一个定时器,在超时未收到ACK后发起重传;
  另一种情况是接收端收到了数据分组并回复了ACK,但ACK在网络中丢失。发送端未收到ACK,同样会发起超时重传,此时接收端会收到重复数据,接收端根据SN判断为重复数据则丢弃,并再次回复ACK。

==> 关于超时重传:

  超时重传的关键在于如何设置超时时间RTO(RTO = Retransmission Time Out,重传超时时间)。
TCP通过测量RTT来计算RTO(RTT = Round Trip Time,一个连接上的往返时间)。
  TCP并不会为每一个发出的数据都测量RTT,实际上是有一个 “测量定时器”(1 秒),每次测量即可得到一次传输的RTT,称为 “SampleRTT”。(重传报文和ACK不会被测量)
  由于网络传输中时延波动很大,TCP需要进行“消抖”来获得一个平滑的RTT平均值,称为 “EstimateRTT”:

EstimatedRTT = 0.875 * EstimatatedRTT + 0.125 * SampleRTT
// RTT = 0.9 * old_rtt + 0.1 * cur_rtt

  在最初的RTO算法中,RTO等于RTT的2倍:(RTO过小则会引起不必要的重传,RTO过大则会导致重传不及时)

RTO = 2 * EstimatedRTT

  这种方法虽然消除了当次的RTT测量结果的剧烈抖动,但却无法及时跟上RTT的变化,因此需要引入对RTT的方差跟踪:

DevRTT = (1 - β) * DevRTT + β * |SampleRTT - EstimatedRTT|

  最后,RTO的计算公式为:

RTO = EstimatedRTT + 4 * DevRTT
//大致相当于 2倍 RTT
==> 关于快速重传:

  快速重传的目的是为了避免由于超时重传而使拥塞窗口cwnd直接降为1,导致发送速率下降过大。
当接收端收到不连续的报文分组,就会立即向发送端回复ACK(收到乱序报文分组后,接收端不会进行 延迟ACK确认)。
  发送端收到连续的三个相同的ACK后,即启动 快速重传 及 快速恢复。(当发生丢包,TCP首先要做的就是对丢弃的报文进行重传;其次则是要进行拥塞控制,因为丢包表明网络中已经发生了拥塞,快速重传对应的拥塞算法即是快速恢复)

为什么是3次冗余ACK:
  避免那些因为【延迟】而并非【丢包】导致乱序到达的TCP数据报文触发不必要的重传。
  TCP包封装在IP包内,IP包在传输时是乱序的,即使TCP在发送端按序发送,在接收端也可能乱序到达。所以,当接收端收到的报文乱序,可能只是延迟,而非丢包。


2. TCP如何实现高效:

滑动窗口 + 流量控制 + 拥塞控制

2.1 滑动窗口:

  通过超时重传 ,TCP已经实现了可靠传输。但在可靠传输的前提下还需要考虑提高传输效率,如果按照简单的发送一包数据等待回复一个ACK的方式,中间网络大部分时间都会处于空闲状态,网络带宽利用率低。
  解决方法是发送端同时向网络中注入多个数据分组,注入速率由一个滑动窗口控制。
  发送端的发送速率应不大于接收端的接收速率,且不大于中间网络的处理速率。(如果发送速率过大,超出接收端或中间路由器的处理能力,则会引起路由器内存或接收端内存溢出,发生丢包,造成不必要的重传)


  TCP通过 流量控制拥塞控制 来控制发送端的发送速率:

  流量控制 是防止数据输出过快导致对方来不及处理,是 端对端 的控制,只要抑制发送端的发送速率即可;
  拥塞控制 是防止过多的数据涌入网络,导致网络处理不过来,拥塞控制是全局的、系统的、涉及所有主机路由器的控制,提高某个节点上的设备处理能力只会将瓶颈丢到其他节点上,只有当全局的设备趋于平衡的时候,整个网络才能够顺畅运行。

2.2 流量控制:

  接收端通过回复给发送端的ACK中的 “WindowSize” 字段,通知本端接收缓冲区的剩余大小(取决于应用程序的处理速度),即 “通告窗口”(awnd),发送窗口 应不大于 通告窗口的大小,此为 “流量控制”;
  中间网络中的路由器节点并不会主动通知发送端网络中发生了拥塞,而是需要发送端根据网络情况判断拥塞是否发生(例如发生“超时重传”或“RTT时延增大”),发送端通过“慢启动”和“拥塞避免”算法控制 “拥塞窗口”(cwnd)的大小,发送窗口应不大于拥塞窗口,此为 “拥塞控制”。
  综上,发送窗口大小应该取 接收窗口 与 拥塞窗口 中的最小值,即:

W = min(awnd, cwnd)

TIPS:TCP判断网络发生拥塞的事件有两个:超时重传或RTT时延增大。

==> 滑动窗口结构:

在这里插入图片描述

==> 接收窗口结构:

在这里插入图片描述

2.3 拥塞控制:

==> 什么是拥塞:

  路由器因无法处理高速率到达的流量而被迫丢弃数据信息的现象,叫做 拥塞

==> 检测拥塞发生的方法:

  (1)丢包
  (2)时延测量
  (3)ECN显式通知


TCP 的拥塞控制 的四个核心算法是: 慢启动、拥塞避免、快速重传、快速恢复

==> 何时发生慢启动:

  (1)新建的连接,初始需要慢启动;
  (2)当发生 超时重传 后,会改为慢启动;
  (3)当TCP连接处于空闲状态的时间过久,也可能执行慢启动。

==> 慢启动算法的目的(作用):

  由于在 初始传输阶段,未知网络传输能力,需要缓慢探测可用资源,避免在短时间内 大量的注入数据导致拥塞。

==> 与慢启动相关的两个变量:

(1)cwnd
  cwnd = congestion window,表示 拥塞窗口 大小,初始值为 1,在慢启动阶段按指数增长,即 :

cwnd = 2 * cwnd;

(2)ssthresh
  ssthreash = slow start threshhold,慢启动门限值(慢启动阈值),是 慢启动 至 拥塞避免阶段 的转折点。

当 cwnd < ssthresh,使用 慢启动算法,指数增长;
当 cwnd > ssthresh,使用 拥塞避免算法,线性增长;
当 cwnd = ssthresh,使用 二者皆可。
==> 为什么要从 慢启动 转向 拥塞避免算法:

  当慢启动cwnd达到门限值ssthresh之后,再继续增加cwnd拥塞窗口的大小会获得更多的网络带宽资源(假如接收端的通告窗口足够大),但是如果立即全部占用这些资源,可能会导致 网络中的其他TCP连接出现严重的丢包和重传的情况,从而导致整个网络不稳定。

  为了得到更多的 传输资源,且 不致影响其他连接上的传输,TCP采用拥塞避免算法:一旦cwnd增长到门限值 ssthresh 之后,就开始降低增长速度,转为线性增加。

==> 当发生 超时重传 时,拥塞算法的处理:

  当发生超时重传,门限值ssthresh 降为 当前拥塞窗口cwnd值大小的一半,并将cwnd降为1,重新开始执行慢启动,即:

ssthresh = cur_cwnd / 2
cwnd = 1
==> 当发生 快速重传 时,拥塞算法的处理(快速恢复):

  当发生快速重传,门限值ssthresh 同样降为 当前拥塞窗口cwnd值大小的一半,但cwnd并不会降为 1 重新开始慢启动(这会导致很大程度降低网络传输效率),而是降为当前cwnd的一半,并开始执行 拥塞避免算法,即:

ssthresh = cur_cwnd / 2
cwnd = cur_cwnd / 2

  也有部分 快速恢复 的实现方式是将 cwnd 设置为 cwnd = cwnd / 2 + 3 * MSS,因为之前收到的3个重复ACK说明已经接收端在丢失的那包数据之后又至少收到了3包数据。

==> 一个典型的拥塞控制过程:

在这里插入图片描述

(1)慢启动:
  在横坐标 0 - 4 阶段,cwnd初始值=1,ssthresh初始值=16,cwnd按指数速度增长至16后,完成慢启动阶段,转为 拥塞避免阶段;

(2)拥塞避免:
  在横坐标 4 - 12 阶段,cwnd按线性增长,这个阶段没有门限值,当发生重传时(拥塞发生)则结束此阶段;

(3)拥塞发生:
  在横坐标 12 处,发生超时重传,此时:

ssthresh = cur_cwnd / 2 = 24 / 2 = 12
cwnd = 1

(4)慢启动:
  在横坐标 12 - 17 阶段,由于发生了超时重传,TCP开始重新执行慢启动,cwnd从1开始指数增长至新的ssthresh门限值12后,再次转入拥塞避免;

(5)拥塞避免:
  在横坐标 17 - 21 阶段,cwnd按线性增长,当增至 cwnd = 16时,发生了快速重传(收到连续3个相同的ACK),此时转入快速恢复;

(6)快速恢复:
  在横坐标 21 处,由于发生快速重传,TCP进入快速恢复:

ssthresh = cur_cwnd / 2 = 16 / 2 = 8
cwnd = cur_cwnd / 2 = 16 / 2 = 8

//某些算法中:
//cwnd = cur_cwnd / 2 + 3 = 16 / 2 + 3 = 11

  随后再次进入 拥塞避免阶段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值