【计算机网络】Transmission-Control-Protocol拥塞控制

TCP概述.

TCP是Transmission Control Protocol的首字母缩略词,意为传输控制协议。从这个名字中我们隐约可以看出TCP对于它所传输的数据,是有着一定的“控制”能力的。作为使用在运输层的两个主要协议之一,提到TCP就不得不简单说说另一个主要协议——UDP用户数据报协议(User Datagram Protocol)。UDP只在网络层IP协议的数据包服务之上增加了很少的功能,复用、分用以及差错检测。相较于TCP,UDP没有连接、没有确认、没有拥塞控制。
这里我们主要讨论关于拥塞控制的细节。由于UDP没有拥塞控制,所以源主机就没有“网络拥塞”这一概念,这就意味着源主机的发送速率完全不会因为网络中实际出现的拥塞而降低。很多的实时应用是要求源主机以恒定的速率来发送数据的,并且允许在发生拥塞时丢失一些数据,但绝对不允许过大的时延,例如IP电话、实时视频会议(这个寒假大家用得很多的Zoom、腾讯会议等)、实时战斗游戏(很熟悉的LOL的MOBA游戏模式)等等都会使用UDP来完成数据传输。
但在很多需要保证数据不丢失、对网络通信质量很高的应用场景中,例如文件传输,使用UDP协议可能会发生的丢包就让人难以忍受,这里就需要使用TCP协议来进行传输,保证数据的可靠交付。我们知道,在计算机网络中,数字带宽、交换节点的缓存以及处理机等都属于网络的资源,而当某一时间对某一网络资源的需求超过了该资源的可用量时,网络的性能就会变坏,这样的情况叫做拥塞。当有多种网络资源供应不足时,整个网络的性能就会急剧下降,使得网络的吞吐量随着输入负荷的增加而暴跌。
有人也许会说,资源不足,只要增加资源就行了。但实际上网络拥塞是由于很多因素造成的,简单地增加资源很可能会适得其反,使得网络通信环境进一步恶化。拥塞会导致很多无法传输的数据被丢弃,而发送方又会采取超时重传措施,使得整个网络的拥塞雪上加霜。至此,TCP协议中拥塞控制功能的重要性就显现出来了。

拥塞控制大观.

拥塞控制是防止过多的数据注入到网络,这样可以使得网络中的路由器、链路等不至于过载。拥塞控制是一个全局性的过程,它涉及到所有的主机、路由器以及与网络性能降低有关的所有因素。但一台主机上TCP端点迟迟收不到对方发来的确认消息时,它会猜想网络可能是拥塞了,却不会知道网络上何处发生了拥塞,也不知道拥塞的原因是什么。一个与拥塞控制联系密切的概念叫做流量控制。流量控制是一个点对点通信量的控制,它要做的是抑制发送端的发送速度,保证接收端来得及接收。
实践中设计拥塞控制是很困难的事,因为它是一个动态的问题。随着网络的高速化,缓存过小而导致的丢包现象很频繁。但丢包现象正是网络拥塞的表现,而不是原因。很多情况下,恰恰是拥塞控制机制本身成了网络性能恶化甚至导致死锁的原因。
从控制理论的角度来考虑网络拥塞,可以将拥塞控制分为开环控制和闭环控制两种。所谓开环就是在设计网络的时候就事先考虑可能导致拥塞的因素,力求整个网络不会出现拥塞,而整个系统一旦运行起来,就不再中途更改了。而闭环控制是基于反馈环路的概念,主要有以下几种措施:

  • 监测网络系统,以便知道何时、何处发生拥塞;
  • 将拥塞发生的信息传递到可以采取措施的地方;
  • 调整网络系统的运行以解决拥塞。

TCP的拥塞控制.

TCP的拥塞控制算法有四种:

  • 慢启动(Slow-Start)
  • 拥塞避免(Congestion Aviodance)
  • 快重传(Fast Retransmit)
  • 快恢复(Fast Recovery)

我们在讨论数据传输时,会指定一个发送端和一个接收端。但实际上TCP是支持全双工通信的,便于讨论我们做出这样的假设。此外,我们认为接收方总是有足够大的缓存空间,而发送方的窗口大小受到网络拥塞程度的控制。

1.慢启动算法(Slow-Start).

慢启动算法的思路是:当主机开始发送数据时,由于并不清楚网络的负荷情况,所以如果在一开始立即把大量的数据字节注入到网络,就很有可能引起网络拥塞。大量的经验事实证明:较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。最新的RFC 5681把初始拥塞窗口cwnd(congestion window)设置为不超过2至4个SMSS的数值。SMSS是发送方最大报文段的数值,全称是Sender Maximum Segment Size.
具体的规定如下:
在这里插入图片描述
上述规定用以限制cwnd的初始大小。
慢启动算法还规定,每收到一个对新报文段的确认之后,可以把拥塞窗口增加最多一个 SMSS 的数值。也就是说Δcwnd=min(N,SMSS),式中N是原先未被确认,但现在被刚收到的确认报文段所确认的字节数。用慢启动算法逐步增大发送方的拥塞窗口cwnd, 可以使分组注入到网络的速率更加合理。
如果网络中的传输一切正常,也就是说发送方发送cwnd大小的数据,接收方全部收到并且予以确认。那么下一轮次中cwnd的大小将是上一轮的两倍。因此使用慢启动算法后,每经过一个传输轮次,cwnd的大小就加倍。而传输轮次的时间并不是固定不变的。一个传输轮次经历的时间实际上就是往返时间RTT,RTT并不是不变的,它是将cwnd所允许发送的报文段都发送出去,并且受到接收方对最后一个字节的确认的时间。例如当前的cwnd=4,那么RTT就是发送发连续发送4个报文段,并且收到这4个报文段对应的确认所经历的时间。
注意,慢启动算法的“慢”并不是说cwnd增长的速度慢,下面我们可以看到慢启动算法的增长速率要比拥塞控制算法快得多。这个“慢”是指在最初开始发送报文段时,对cwnd存在一个限制,目的是为了试探一下网络中的拥塞情况,然后逐步增大cwnd的值。这要比将cwnd设置为很大的数,一下子将很多报文段注入网络要“慢得多”。

2.拥塞避免算法(Congestion Aviodance).

拥塞避免算法的思路是让拥塞窗口cwnd缓慢变大,即经过每一个往返时间 RTT 就将发送方的拥塞窗口cwnd+1,而不是像慢启动算法那样使得cwnd成倍增加。这样的增加策 略叫做“加法增长”,线性增长的拥塞避免算法比慢启动算法的拥塞窗口增长慢得多。 注意:我们设置了一个慢启动门限ssthresh状态变量。
【计算机网络】Transmission-Control-Protocol拥塞控制_第1张图片
拥塞避免不是真的能够避免拥塞的发生,它只是将cwnd控制为线性增长,使得网络比较不容易发生拥塞。
【计算机网络】Transmission-Control-Protocol拥塞控制_第2张图片
我们以谢希仁老师的《计算机网络》P234的图为例,详述一下整个过程。
首先cwnd置为1,ssthresh初始为16. 四个轮次过后cwnd增长为16,根据约定,这时开始使用拥塞控制算法,即线性增长。当cwnd=24时,网络发生了超时,意味着可能出现了拥塞,于是将cwnd重新置为1,并调整ssthresh的值。调整的策略是令新的ssthresh=发生超时的cwnd的一半。这时继续执行慢启动算法,当到达ssthresh的值12时,再次切换为拥塞控制算法进行线性增长。接下来的过程,我们需要先阐述快重传(Fast Retransmit)和快恢复(Fast Recovery)机制,再进行描述。

3.快重传(Fast Retransmit) & 快恢复(Fast Recovery)

首先,快重传算法可以让发送方尽早地知道发生了个别报文段的丢失。快重传算法要求发送方不能等待自己要发送消息时才进行捎带确认,而是要求收到报文段之后立即发送确认——即使是收到了失序的报文段也要发送对已收到的有序报文段的确认。发送方只要连续收到三个重复确认,就知道接收方确实没有收到中间丢掉的数据,因而立即进行重传。这样就不会出现超时,发送方也不会误以为出现了网络拥塞。快重传算法可以使整个网络的吞 吐量提高 20%.
而当发送方知道现在的问题只是丢失了个别段时,他不会启动慢开始算法,而是执行快恢复算法。将慢开始门限值ssthresh调整为 cwnd/2,与此同时设置拥塞窗口 cwnd=ssthresh,开始执行拥塞避免算法。另外,还有一些快恢复算法将cwnd设置为 ssthresh+3*SMSS,这样做的理由是:既然发送方连续收到了3个重复的确认,表明已经有三个分组离开了网络, 因此可以将 cwnd 适当地扩大。这些具体的措施都是在实际应用中灵活多变的,并没有要求固定是哪一种数量关系。
【计算机网络】Transmission-Control-Protocol拥塞控制_第3张图片
现在我们继续讨论第20轮次之后发生的情况。如快恢复算法中所描述的,发送方接受到了连续的3个确认,就是图中的3-ACK,它知道接收方只是丢失了中间的个别数据,于是执行快恢复算法。将ssthresh设置为cwnd/2=8,并且cwnd=ssthresh=8,由此执行拥塞避免算法。

习题总结.

【计算机网络】Transmission-Control-Protocol拥塞控制_第4张图片
【计算机网络】Transmission-Control-Protocol拥塞控制_第5张图片【计算机网络】Transmission-Control-Protocol拥塞控制_第6张图片
【计算机网络】Transmission-Control-Protocol拥塞控制_第7张图片

你可能感兴趣的:(计算机网络)