tcp的拥塞控制?

本文详细介绍了TCP拥塞控制的概念及其重要性,并深入探讨了几种关键的拥塞控制方法,包括慢开始、拥塞避免、快重传和快恢复算法。通过这些方法,TCP能够有效地避免网络拥塞并提高整体网络性能。

tcp的拥塞控制

1.拥塞:

即对资源的需求超过了可用的资源。若网络中许多资源同时供应不足,网络的性能就要明显变坏,整个网络的吞吐量随之负荷地增大而下降

拥塞控制:防止过多的数据注入到网络中,这样可用是网络中的路由器或链路不至过载。
拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,设计到所有主机、路由器,以及与降低网络传输性能有关的所有因素

流量控制:指点对点通信量的控制,是端到端的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收
拥塞控制代价:需要获得网络内部流量分布的信息。在实施拥塞控制之前,还需要在结点之间交换信息和各种命令,以便选择控制的策略和实施控制,这样就产生了额外的开销。

2.几种拥塞控制方法

慢开始,拥塞避免,快重传,快恢复

慢开始:

先探测,由小到大逐渐增大发送窗口,也就是说,先把拥塞窗口cwnd设置为一个最大报文段MSS,收到确认后,把cwnd增多至一个mss数值(设mss=1,则发送过程1->2->4->8)

**为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量(如何设置ssthresh)。慢开始门限ssthresh的用法如下:
- 当 cwnd < ssthresh 时,使用上述的慢开始算法。
- 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
- 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。

拥塞避免算法

让拥塞窗口缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd+1,而不是加倍,这样拥塞窗口按线性规律缓慢增长,比慢开始算法缓慢很多

无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送 方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生 拥塞的路由器有足够时间把队列中积压的分组处理完毕。

这里写图片描述
1. 当TCP连接进行初始化时候,把拥塞窗口cwnd置为1。前面已说过,为了便于理解,图中的窗口单位不使用字节而使用报文段的个数。慢开始门限的初始值设置为16个报文段
2. 在执行慢开始算法时,拥塞窗口 cwnd 的初始值为1。以后发送方每收到一个对新报文段的确认ACK,就把拥塞窗口值另1,然后开始下一轮的传输(图中横坐标为传输轮次)。因此拥塞窗口cwnd 随着传输轮次按指数规律增长。当拥塞窗口cwnd增长到慢开始门限值ssthresh时(即当cwnd=16时),就改为执行拥塞控制算法,拥塞窗口按线 性规律增长。
3. 假定拥塞窗口的数值增长到24时,网络出现超时(这很可能就是网络发生拥塞了)。更新后的ssthresh值变为12(即变为出现超时时的拥塞窗口数值 24的一半),拥塞窗口再重新设置为1,并执行慢开始算法。当cwnd=ssthresh=12时改为执行拥塞避免算法,拥塞窗口按线性规律增长,每经过 一个往返时间增加一个MSS的大小。


例题:有一条TCP连接,它的最大报文段长度为4KB,TCP拥塞窗口为24KB,这时候发生超时,那么该拥塞窗口变为了(4KB)
发生拥塞,此时如果没有经过若干次正常的接收,则拥塞窗口从4开始增长
4->8->9->10->11…
如果经过2次正常的接收,则拥塞窗口变成了9KB,即9->10->11…


快重传和快恢复

如果发送方设置的超时计时器时限已到但还没有收到确认,那么很可能是网络出现了拥塞,致使报文段在网络中的某处被丢弃。这时,TCP马上把拥塞窗口 cwnd 减小到1,并执行慢开始算法,同时把慢开始门限值ssthresh减半。这是不使用快重传的情况。

快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时才进行捎带确认。
这里写图片描述
1.接收方收到了M1和M2后发出确认,,现在假定接收方没有收到M3但是接着收到了M4,显然接收方不能确认M4,因为M4是收到的失序报文段,根据可靠传输原理,接收方可以什么都不做,也可以在适当时机方法发送一次对M2的确认。
2.但按照快重传算法的规定,接收方应及时发送对M2的重复确认,这样做可以让发送方及早知道报文段M3没有到达接收方。发送方接着发送了M5和M6。
3.接收方收到这两个报文后,也还要再次发出对M2的重复确认。这样,发送方共收到了 接收方的四个对M2的确认,其中后三个都是重复确认。
4.快重传算法还规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段M3,而不必 继续等待M3设置的重传计时器到期。由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高约20%

与快重传配合使用的还有快恢复算法,其过程有以下两个要点:
  1. 当发送方连续收到三个重复确认,就执行”乘数减小“算法,把慢开始门限ssthresh减半,这是为了预防网络发生拥塞,接下去不执行慢开始算法!
  2. 由于发送方现在认为网络很可能没有发送拥塞,因此与慢开始不同之处是现在不执行慢开始算法,即拥塞窗口cwnd现在不设置为1,而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢线性增大

下图给出了快重传和快恢复的示意图,并标明了“TCP Reno版本”。

区别:新的 TCP Reno 版本在快重传之后采用快恢复算法而不是采用慢开始算法。
这里写图片描述
也有的快重传实现是把开始时的拥塞窗口cwnd值再增大一点,即等于 ssthresh + 3 X MSS 。这样做的理由是:既然发送方收到三个重复的确认,就表明有三个分组已经离开了网络。这三个分组不再消耗网络 的资源而是停留在接收方的缓存中。可见现在网络中并不是堆积了分组而是减少了三个分组。因此可以适当把拥塞窗口扩大了些。

在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用。
### TCP拥塞控制机制详解 TCP拥塞控制是一种动态调整数据传输速率的机制,旨在避免因网络资源过载而导致的数据丢失和性能下降。该机制通过感知网络状态并调整发送速率,确保网络资源的高效利用,同避免对网络造成过大的压力[^3]。 #### 拥塞控制的基本原理 在TCP通信中,发送方通过调整拥塞窗口(cwnd)来控制发送速率。拥塞窗口的大小由网络的拥塞程度决定,而非接收方的缓冲区容量。当网络出现拥塞迹象(如丢包、延迟增加),发送方会减小cwnd,以降低发送速率;当网络状况良好,cwnd则逐步增大,以充分利用带宽资源[^2]。 拥塞控制的核心思想是通过反馈机制(如ACK确认和RTT测量)来判断网络是否处于拥塞状态,并根据特定算法调整cwnd。这一过程通常包括以下几个阶段: 1. **慢启动(Slow Start)** 初始阶段,发送方以指数方式增长cwnd,直到达到慢启动阈值(ssthresh)或检测到拥塞。这一阶段的目的是快速探测网络的可用带宽。 2. **拥塞避免(Congestion Avoidance)** 当cwnd超过ssthresh后,进入线性增长阶段,即每经过一个RTT,cwnd仅增加1MSS(Maximum Segment Size)。这一阶段的目标是避免网络突然过载[^2]。 3. **快重传(Fast Retransmit)** 当发送方连续收到三个重复的ACK(即接收方检测到数据包丢失),则立即重传丢失的数据包,而无需等待超。该机制减少了重传延迟,提高了传输效率[^2]。 4. **快恢复(Fast Recovery)** 快重传之后,cwnd不会直接降为1,而是为ssthresh的一半,并进入拥塞避免阶段。这种方式避免了因单个丢包而导致的过度降速,提升了整体吞吐量。 #### 拥塞控制算法的实现示例 以下是一个简化的TCP Reno拥塞控制算法的模拟实现,展示了慢启动、拥塞避免、快重传和快恢复的基本逻辑: ```python class TCPCongestionControl: def __init__(self, initial_cwnd=1, mss=1460, rtt=0.1): self.cwnd = initial_cwnd # 拥塞窗口大小(单位MSS) self.ssthresh = 64 # 慢启动阈值 self.mss = mss # 最大报文段长度 self.rtt = rtt # 往返间 self.dup_ack_count = 0 # 重复ACK计数 def on_ack_received(self): if self.cwnd < self.ssthresh: # 慢启动阶段:指数增长 self.cwnd += 1 else: # 拥塞避免阶段:线性增长 self.cwnd += 1 / self.cwnd def on_packet_loss(self): # 快重传触发后的处理 self.ssthresh = max(self.cwnd // 2, 2) self.cwnd = self.ssthresh self.dup_ack_count = 0 def on_duplicate_ack(self): self.dup_ack_count += 1 if self.dup_ack_count == 3: # 触发快重传 self.on_packet_loss() # 快恢复:将cwnd为ssthresh + 3(RFC 5681) self.cwnd = self.ssthresh + 3 def get_cwnd_bytes(self): return self.cwnd * self.mss # 模拟拥塞控制过程 tcp_cc = TCPCongestionControl() # 初始状态 print(f"初始拥塞窗口: {tcp_cc.get_cwnd_bytes()} 字节") # 模拟正常ACK接收 for _ in range(5): tcp_cc.on_ack_received() print(f"慢启动阶段后拥塞窗口: {tcp_cc.get_cwnd_bytes()} 字节") # 模拟三次重复ACK(触发快重传) for _ in range(3): tcp_cc.on_duplicate_ack() print(f"快重传后拥塞窗口: {tcp_cc.get_cwnd_bytes()} 字节") # 模拟恢复阶段 tcp_cc.on_ack_received() print(f"快恢复后拥塞窗口: {tcp_cc.get_cwnd_bytes()} 字节") ``` 该示例模拟了TCP Reno算法中拥塞窗口的动态变化过程,包括慢启动、拥塞避免、快重传和快恢复的实现逻辑。 #### 拥塞控制的挑战与改进 尽管TCP Reno等传统拥塞控制算法在多数场景下表现良好,但在高延迟、高带宽(BDP大)的网络中,其基于丢包的机制可能导致性能下降。例如,在高延迟网络中,RTT的波动可能影响拥塞状态的判断,而丢包可能被误认为是网络拥塞,而非链路质量的问题。 为此,后续的TCP版本(如TCP Vegas、TCP Cubic)引入了基于延迟的拥塞检测机制,以提高在高速网络中的性能[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值