网站制作公司网站建设公司,巩义网站推广优化,策划方案范文,店铺网页设计#xff08;★★#xff09;代表非常重要的知识点#xff0c;#xff08;★#xff09;代表重要的知识点。 一、TCP 流量控制#xff08;★★#xff09;
1. 利用滑动窗口实现流量控制
一般说来#xff0c;我们总是希望数据传输得更快一些。但如果发送方把数据发送得… ★★代表非常重要的知识点★代表重要的知识点。 一、TCP 流量控制★★
1. 利用滑动窗口实现流量控制
一般说来我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快接收方就可能来不及接收这就会造成数据的丢失。所谓流量控制flow control就是让发送方的发送速率不要太快要让接收方来得及接收因此可以说流量控制是一个速度匹配服务匹配发送方的发送速率与接收方的读取速率。
利用滑动窗口机制可以很方便地在 TCP 连接上实现对发送方的流量控制滑动窗口的基本原理已在数据链路层中介绍过【数据链路层 II流量控制与可靠传输机制【★★★★★】】这里要介绍的是 TCP 如何使用窗口机制来实现流量控制。
TCP 要求发送方维持一个接收窗口 rwndreceiver window即接收方允许连续接收的能力单位是字节接收方根据当前接收缓存的大小动态地调整接收窗口的大小其大小反映了接收方的容量。接收方将其放在 TCP 报文段首部中的“窗口”字段以通知发送方。发送方的发送窗口不能超过接收方给出的接收窗口值以限制发送方向网络注入报文的速率。
下面通过下图所示的例子说明如何利用滑动窗口机制进行流量控制。 假设数据只从 A 发往 B 而 B 仅向 A 发送确认报文段。在连接建立时B 可通过设置确认报文段首部中的窗口字段来将 rwnd 通知给 A 。发送方 A 总是根据最新收到的 rwnd 值来限制自己发送窗口的大小从而将未确认的数据量控制在 rwnd 大小之内保证 A 不会使 B 的接收缓存溢出发送方的发送窗口不能超过接收方给出的接收窗口的数值。B 告诉了 A“ 我的接收窗口 rwnd 400”。请注意 TCP 的窗口单位是字节不是报文段。
TCP 连接建立时的窗口协商过程在图中没有显示出来。再设每一个报文段为 100 字节长而数据报文段序号的初始值设为 1见图中第一个箭头上面的序号 seq 1 图中右边的注释可帮助理解整个过程。请注意图中箭头上面大写 ACK 表示首部中的确认位 ACK 小写 ack 表示确认字段的值。
我们应注意到接收方的主机 B 进行了三次流量控制。第一次把窗口减小到 rwnd 300 第二次又减到 rwnd 100 最后减到 rwnd 0 即不允许发送方再发送数据了。这种使发送方暂停发送的状态将持续到主机 B 重新发出一个新的窗口值为止。我们还应注意到 B 向 A 发送的三个报文段都设置了 ACK 1, 只有在 ACK 1 时确认号字段才有意义。
现在我们考虑一种情况。在上图中 B 向 A 发送了零窗口的报文段后不久 B 的接收缓存又有了一些存储空间。于是 B 向 A 发送了 rwnd 400 的报文段。然而这个报文段在传送过程中丢失了。A 一直等待收到 B 发送的非零窗口的通知而 B 也一直等待 A 发送的数据。如果没有其他措施这种互相等待的死锁局面将一直延续下去。
为了解决这个问题 TCP 为每一个连接设有一个持续计时器persistence timer。只要 TCP 连接的一方收到对方的零窗口通知就启动持续计时器。若持续计时器设置的时间到期就发送一个零窗口探测报文段仅携带 1 字节的数据而对方就在确认这个探测报文段时给出了现在的窗口值。如果窗口仍然是零那么收到这个报文段的一方就重新设置持续计时器。如果窗口不是零那么死锁的僵局就可以打破了。 注 TCP 规定即使设置为零窗口也必须接收以下几种报文段零窗口探测报文段、确认报文段和携带紧急数据的报文段。 传输层和数据链路层的流量控制的区别是
传输层实现的是端到端即两个进程之间的流量控制数据链路层实现的是两个中间的相邻结点之间的流量控制。此外数据链路层的滑动窗口协议的窗口大小不能动态变化传输层的窗口大小则可以动态变化。
2. TCP 的传输效率拓展
前面已经讲过应用进程把数据传送到 TCP 的发送缓存后剩下的发送任务就由 TCP 来控制了。可以用不同的机制来控制 TCP 报文段的发送时机。例如
第一种机制是 TCP 维持一个变量它等于最大报文段长度 MSSMaximum Segment Size。只要缓存中存放的数据达到 MSS 字节时就组装成一个 TCP 报文段发送出去。第二种机制是由发送方的应用进程指明要求发送报文段即 TCP 支持的推送push操作。第三种机制是发送方的一个计时器期限到了这时就把当前已有的缓存数据装入报文段但长度不能超过 MSS发送出去。
但是如何控制 TCP 发送报文段的时机仍然是一个较为复杂的问题。例如一个交互式用户使用一条 TELNET 连接运输层为 TCP 协议。假设用户只发 1 个字符加上 20 字节的首部后得到 21 字节长的 TCP 报文段。再加上 20 字节的 IP 首部形成 41 字节长的 IP 数据报。在接收方TCP 立即发出确认构成的数据报是 40 字节长假定没有数据发送。若用户要求远地主机回送这一字符则又要发回 41 字节长的 IP 数据报和 40 字节长的确认 IP 数据报。这样用户仅发 1 个字符时线路上就需传送总长度为 162 字节共 4 个报文段。当线路带宽并不富裕时这种传送方法的效率的确不高。因此应适当推迟发回确认报文并尽量使用捎带确认的方法。
在 TCP 的实现中广泛使用 Nagle 算法。算法如下若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存则发送方就把第一个数据字节先发送出去把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后再把发送缓存中的所有数据组装成一个报文段发送出去同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时用这样的方法可明显地减少所用的网络带宽。Nagle 算法还规定当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时就立即发送一个报文段。这样做就可以有效地提高网络的吞吐量。
另一个问题叫做糊涂窗口综合征silly window syndrome有时也会使 TCP 的性能变坏。设想一种情况 TCP 接收方的缓存已满而交互式的应用进程一次只从接收缓存中读取 1 个字节这样就使接收缓存空间仅腾出 1 个字节然后向发送方发送确认并把窗口设置为 1 个字节但发送的数据报是 40 字节长。接着发送方又发来 1 个字节的数据请注意发送方发送的 IP 数据报是 41 字节长。接收方发回确认仍然将窗口设置为 1 个字节。这样进行下去使网络的效率很低。
要解决这个问题可以让接收方等待一段时间使得或者接收缓存已有足够空间容纳一个最长的报文段或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一接收方就发出确认报文并向发送方通知当前的窗口大小。此外发送方也不要发送太小的报文段而是把数据积累成足够大的报文段或达到接收方缓存的空间的一半大小。
上述两种方法可配合使用。使得在发送方不发送很小的报文段的同时接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。
二、TCP 拥塞控制★★
1. 拥塞控制的一般原理 拥塞控制是指防止过多的数据注入网络保证网络中的路由器或链路不致过载。出现拥塞时端点并不了解拥塞发生的细节对通信的端点来说拥塞往往表现为通信时延的增加。 在计算机网络中的链路容量即带宽、交换结点中的缓存和处理机等都是网络的资源。在某段时间若对网络中某一资源的需求超过了该资源所能提供的可用部分网络的性能就要变坏。这种情况就叫做拥塞congestion。可以把出现网络拥塞的条件写成如下的关系式
∑ 对资源的需求 可用资源
若网络中有许多资源同时呈现供应不足网络的性能就要明显变坏整个网络的吞吐量将随输入负荷的增大而下降。
有人可能会说“只要任意增加一些资源例如把结点缓存的存储空间扩大或把链路更换为更高速率的链路或把结点处理机的运算速度提高就可以解决网络拥塞的问题。”其实不然。这是因为网络拥塞是一个非常复杂的问题。简单地采用上述做法在许多情况下不但不能解决拥塞问题而且还可能使网络的性能更坏。
网络拥塞往往是由许多因素引起的。例如当某个结点缓存的容量太小时到达该结点的分组因无存储空间暂存而不得不被丢弃。现在设想将该结点缓存的容量扩展到非常大于是凡到达该结点的分组均可在结点的缓存队列中排队不受任何限制。由于输出链路的容量和处理机的速度并未提高因此在这队列中的绝大多数分组的排队等待时间将会大大增加结果上层软件只好把它们进行重传因为早就超时了。由此可见简单地扩大缓存的存储空间同样会造成网络资源的严重浪费因而解决不了网络拥塞的问题。
又如处理机处理的速率太慢可能引起网络的拥塞。简单地将处理机的速率提高可能会使上述情况缓解一些但往往又会将瓶颈转移到其他地方。问题的实质往往是整个系统的各个部分不匹配。只有所有的部分都平衡了问题才会得到解决。
拥塞常常趋于恶化。如果一个路由器没有足够的缓存空间它就会丢弃一些新到的分组。但当分组被丢弃时发送这一分组的源点就会重传这一分组甚至可能还要重传多次。这样会引起更多的分组流入网络和被网络中的路由器丢弃。可见拥塞引起的重传并不会缓解网络的拥塞反而会加剧网络的拥塞。
2. 拥塞控制与流量控制的区别
拥塞控制与流量控制的关系密切它们之间也存在着一些差别。 所谓拥塞控制就是防止过多的数据注入到网络中这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程涉及到所有的主机、所有的路由器以及与降低网络传输性能有关的所有因素。但TCP 连接的端点只要迟迟不能收到对方的确认信息就猜想在当前网络中的某处很可能发生了拥塞但这时却无法知道拥塞到底发生在网络的何处也无法知道发生拥塞的具体原因。是访问某个服务器的通信量过大还是在某个地区出现自然灾害 相反流量控制往往是指点对点通信量的控制是个端到端的问题接收端控制发送端。流量控制所要做的就是抑制发送端发送数据的速率以便使接收端来得及接收。
当然拥塞控制和流量控制也有相似的地方即它们都通过控制发送方发送数据的速率来达到控制效果告诉发送端网络已出现麻烦必须放慢发送速率。
可以用一个简单例子说明这种区别。设某个光纤网络的链路传输速率为 1000 Gbit/s 。有一台巨型计算机向一台个人电脑以 1 Gbit/s 的速率传送文件。显然网络本身的带宽是足够大的因而不存在产生拥塞的问题但如此高的发送速率将导致 PC 可能来不及接收因此必须进行流量控制巨型计算机必须经常停下来以便使个人电脑来得及接收。
但如果有另一个网络其链路传输速率为 1 Mbit/s 而有 1000 台大型计算机连接在这个网络上。假定其中的 500 台计算机分别向其余的 500 台计算机以 100 kbit/s 的速率发送文件。那么现在的问题已不是接收端的大型计算机是否来得及接收而是整个网络的输入负载是否超过网络所能承受的范围。
3. 开环控制和闭环控制拓展
进行拥塞控制需要付出代价。这首先需要获得网络内部流量分布的信息。在实施拥塞控制时还需要在结点之间交换信息和各种命令以便选择控制的策略和实施控制。这样就产生了额外开销。拥塞控制有时需要将一些资源如缓存、带宽等分配给个别用户或一些类别的用户单独使用这样就使得网络资源不能更好地实现共享。十分明显在设计拥塞控制策略时必须全面衡量得失。
在下图中的横坐标是提供的负载offered load代表单位时间内输入给网络的分组数目。因此提供的负载也称为输入负载或网络负载。纵坐标是吞吐量throughput代表单位时间内从网络输出的分组数目。具有理想拥塞控制的网络在吞吐量饱和之前网络吞吐量应等于提供的负载故吞吐量曲线是 45° 的斜线。但当提供的负载超过某一限度时由于网络资源受限吞吐量不再增长而保持为水平线即吞吐量达到饱和。这就表明提供的负载中有一部分损失掉了例如输入到网络的某些分组被某个结点丢弃了。虽然如此在这种理想的拥塞控制作用下网络的吞吐量仍然维持在其所能达到的最大值。 但是实际网络的情况就很不相同了。从上图可看出随着提供的负载的增大网络吞吐量的增长速率逐渐减小。也就是说在网络吞吐量还未达到饱和时就已经有一部分的输入分组被丢弃了。当网络的吞吐量明显地小于理想的吞吐量时网络就进入了轻度拥塞的状态。更值得注意的是当提供的负载达到某一数值时网络的吞吐量反而随提供的负载的增大而下降这时网络就进入了拥塞状态。当提供的负载继续增大到某一数值时网络的吞吐量就下降到零网络已无法工作这就是所谓的死锁deadlock。
从原理上讲寻找拥塞控制的方案无非是寻找使不等式∑ 对资源的需求 可用资源不再成立的条件。这或者是增大网络的某些可用资源如业务繁忙时增加一些链路增大链路的带宽或使额外的通信量从另外的通路分流或减少一些用户对某些资源的需求如拒绝接受新的建立连接的请求或要求用户减轻其负荷这属于降低服务质量。但正如上面所讲过的在采用某种措施时还必须考虑到该措施所带来的其他影响。
实践证明拥塞控制是很难设计的因为它是一个动态的而不是静态的问题。当前网络正朝着高速化的方向发展这很容易出现缓存不够大而造成分组的丢失。但分组的丢失是网络发生拥塞的征兆而不是原因。在许多情况下甚至正是拥塞控制机制本身成为引起网络性能恶化甚至发生死锁的原因。这点应特别引起重视。
由于计算机网络是一个很复杂的系统因此可以从控制理论的角度来看拥塞控制这个问题。这样从大的方面看可以分为开环控制和闭环控制两种方法。开环控制就是在设计网络时事先将有关发生拥塞的因素考虑周到力求网络在工作时不产生拥塞。但一旦整个系统运行起来就不再中途进行改正了。
闭环控制是基于反馈环路的概念主要有以下几种措施
监测网络系统以便检测到拥塞在何时、何处发生。把拥塞发生的信息传送到可采取行动的地方。调整网络系统的运行以解决出现的问题。
有很多的方法可用来监测网络的拥塞。主要的一些指标是由于缺少缓存空间而被丢弃的分组的百分数、平均队列长度、超时重传的分组数、平均分组时延、分组时延的标准差等等。上述这些指标的上升都标志着拥塞的增长。
一般在监测到拥塞发生时要将拥塞发生的信息传送到产生分组的源站。当然通知拥塞发生的分组同样会使网络更加拥塞。
另一种方法是在路由器转发的分组中保留一个比特或字段用该比特或字段的值表示网络没有拥塞或产生了拥塞。也可以由一些主机或路由器周期性地发出探测分组以询问拥塞是否发生。
此外过于频繁地采取行动以缓和网络的拥塞会使系统产生不稳定的振荡。但过于迟缓地采取行动又不具有任何实用价值。因此要采用某种折中的方法。但选择正确的时间常数是相当困难的。
4. TCP 的拥塞控制方法
TCP 进行拥塞控制的算法有四种即慢开始slow-start、拥塞避免congestion avoidance、快重传fast retransmit和快恢复fast recovery。下面就介绍这些算法的原理。为了集中精力讨论拥塞控制我们假定
数据是单方向传送的对方只传送确认报文。接收方总是有足够大的缓存空间因而发送窗口的大小由网络的拥塞程度来决定。
下面讨论的拥塞控制也叫做基于窗口的拥塞控制。发送方在确定发送报文段的速率时既要考虑接收方的接收能力又要从全局考虑不要使网络发生拥塞。为此除了之前介绍的接收窗口 rwndTCP 还要求发送方维持一个叫做拥塞窗口 cwndcongestion window的状态变量。拥塞窗口的大小取决于网络的拥塞程度并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。
发送方控制拥塞窗口的原则是只要网络没有出现拥塞拥塞窗口就可以再增大一些以便把更多的分组发送出去这样就可以提高网络的利用率。但只要网络出现拥塞或有可能出现拥塞就必须把拥塞窗口减小一些以减少注入到网络中的分组数以便缓解网络出现的拥塞。
发送方又是如何知道网络发生了拥塞呢我们知道当网络发生拥塞时路由器就要丢弃分组。因此只要发送方没有按时收到应当到达的确认报文也就是说只要出现了超时就可以猜想网络可能出现了拥塞。现在通信线路的传输质量一般都很好因传输出差错而丢弃分组的概率是很小的远小于 1% 。因此判断网络拥塞的依据就是出现了超时。
接收窗口的大小可根据 TCP 报文首部的窗口字段通知发送方而发送方如何维护拥塞窗口呢这就是下面讲解的慢开始和拥塞避免算法。为了便于理解下面采用最大报文段长度 MSS 作为拥塞窗口大小的单位。
1慢开始和拥塞避免
① 慢开始算法
慢开始算法的思路是这样的当主机开始发送数据时由于并不清楚网络的负荷情况所以如果立即把大量数据字节注入到网络那么就有可能引起网络发生拥塞。经验证明较好的方法是先探测一下若没有发生拥塞则适当增大拥塞窗口即由小到大逐渐增大发送窗口也就是说由小到大逐渐增大拥塞窗口数值。 【拓展】旧的规定是这样的在刚刚开始发送报文段时先把初始拥塞窗口 cwnd 设置为 1 至 2个发送方的最大报文段 SMSSSender Maximum Segment Size的数值但新的 RFC 5681 把初始拥塞窗口 cwnd 设置为不超过 2 至 4 个 SMSS 的数值。具体的规定如下 I、若 SMSS 2190 字节则设置初始拥塞窗口 cwnd 2 × SMSS 字节且不得超过 2 个报文段。 II、若SMSS 1095 字节且SMSS ≤ 2190 字节则设置初始拥塞窗口 cwnd 3 × SMSS 字节且不得超过 3 个报文段。 III、若 SMSS ≤ 1095 字节则设置初始拥塞窗口 cwnd 4 × SMSS 字节且不得超过 4 个报文段。 可见这个规定就是限制初始拥塞窗口的字节数。 慢开始规定在每收到一个对新的报文段的确认后可以把拥塞窗口增加最多一个 SMSS 的数值。更具体些就是
拥塞窗口 cwnd 每次的增加量 minN , SMSS
其中 N 是原先未被确认的、但现在被刚收到的确认报文段所确认的字节数。不难看出当 N SMSS 时拥塞窗口每次的增加量要小于 SMSS 。用这样的方法逐步增大发送方的拥塞窗口 cwnd 可以使分组注入到网络的速率更加合理。
下面用例子说明慢开始算法的原理。请注意虽然实际上 TCP 是用字节数作为窗口大小的单位。但为叙述方便起见我们用报文段的个数作为窗口大小的单位这样可以使用较小的数字来阐明拥塞控制的原理。
例如发送方向接收方发送数据在一开始发送方先设置 cwnd 1 发送第一个报文段 M1 接收方收到后确认 M1 。发送方收到对 M1 的确认后把 cwnd 从 1 增大到 2于是发送方接着发送 M2 和 M3 两个报文段。接收方收到后发回对 M2 和 M3 的确认。发送方每收到一个对新报文段的确认重传的不算在内就使发送方的拥塞窗口加 1 因此发送方在收到两个确认后 cwnd 就从 2 增大到 4 并可发送 M4 ~ M7 共 4 个报文段见下图所示) 。因此使用慢开始算法后每经过一个传输轮次transmission round即往返时间 RTT 拥塞窗口 cwnd 就会加倍即 cwnd 的值随传输轮次指数增长。 这里我们使用了一个名词——传输轮次。从上图可以看出一个传输轮次所经历的时间其实就是往返时间 RTT请注意 RTT 并非是恒定的数值。使用“传输轮次”是更加强调把拥塞窗口 cwnd 所允许发送的报文段都连续发送出去并收到了对已发送的最后一个字节的确认。例如拥塞窗口 cwnd 的大小是 4 个报文段那么这时的往返时间 RTT 就是发送方连续发送 4 个报文段并收到这 4 个报文段的确认后总共经历的时间。
我们还要指出慢开始的“慢”并不是指 cwnd 的增长速率慢而是指在 TCP 开始发送报文段时先设置 cwnd 1 使得发送方在开始时只发送一个报文段目的是试探一下网络的拥塞情况然后再逐渐增大 cwnd 。这当然比设置大的 cwnd 值一下子把许多报文段注入到网络中要“慢得多”。这对防止网络出现拥塞是一个非常好的方法。
顺便指出上图只是为了说明慢开始的原理。在 TCP 的实际运行中发送方只要收到一个对新报文段的确认其拥塞窗口 cwnd 就立即加 1 并可以立即发送新的报文段而不需要等这个轮次中所有的确认都收到后如上图所示的那样再发送新的报文段。
② 拥塞避免算法
拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢地增大即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1 而不是像慢开始阶段那样加倍增长。因此在拥塞避免阶段就有“加法增大”Additive Increase, AI 的特点。这表明在拥塞避免阶段拥塞窗口 cwnd 按线性规律缓慢增长比慢开始算法的拥塞窗口增长速率缓慢得多。 注请注意因为现在是讲原理把窗口的单位改为报文段的个数。实际上应当是“拥塞窗口仅增加一个 MSS 的大小单位是字节”。在具体实现拥塞避免算法的方法时可以这样来完成只要收到一个新的确认就使拥塞窗口 cwnd 增加MSS × MSS / cwnd个字节。例如假定 cwnd 等于 10 个 MSS 的长度而 MSS 是 1460 字节。发送方可一连发送 14600 字节即 10 个报文段。假定接收方每收到一个报文段就发回一个确认。于是发送方每收到一个新的确认就把拥塞窗口稍微增大一些即增大 0.1 MSS 146 字节。经过一个往返时间 RTT或一个传输轮次后发送方共收到 10 个新的确认拥塞窗口就增大了 1460 字节正好是一个 MSS 的大小。 为了防止拥塞窗口 cwnd 增长过大引起网络拥塞还需要设置一个慢开始门限 ssthresh 状态变量阈值。慢开始门限 ssthresh 的用法如下
当 cwnd ssthresh 时使用上述的慢开始算法。当 cwnd ssthresh 时停止使用慢开始算法而改用拥塞避免算法。当 cwnd ssthresh 时既可使用慢开始算法也可使用拥塞避免算法。
③ 网络拥塞的处理
无论在慢开始阶段还是在拥塞避免阶段只要发送方判断网络出现拥塞未按时收到确认就要首先把慢开始门限 ssthresh 设置为出现拥塞时的发送方的 cwnd 值的一半但不能小于 2然后把拥塞窗口 cwnd 重新设置为 1 执行慢开始算法。这样做的目的是迅速减少主机发送到网络中的分组数使得发生拥塞的路由器有足够时间把队列中积压的分组处理完。
下图用具体例子说明了在拥塞控制的过程中TCP 的拥塞窗口 cwnd 是怎样变化的。图中的的数字 ① 至 ⑤ 是特别要注意的几个点。现假定 TCP 的发送窗口等于拥塞窗口。为了便于理解图中的窗口单位不使用字节而使用报文段的个数。 当 TCP 连接进行初始化时把拥塞窗口 cwnd 置为 1 。在本例中慢开始门限的初始值设置为 16 个报文段即 ssthresh 16 。 在执行慢开始算法时发送方每收到一个对新报文段的确认 ACK 就把拥塞窗口值加 1 然后开始下一轮的传输请注意下图的横坐标是传输轮次 RTT 不是时间此时拥塞窗口 cwnd 随着传输轮次按指数规律增长。 当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时图中的点 ① 此时拥塞窗口 cwnd 16就改为执行拥塞避免算法拥塞窗口按线性规律增长。但请注意“拥塞避免”并非完全能够避免了拥塞利用该方法要完全避免网络拥塞是不可能的“拥塞避免”是说把拥塞窗口控制为按线性规律增长使网络比较不容易出现拥塞。 当拥塞窗口 cwnd 24 时网络出现了超时图中的点 ②发送方判断为网络拥塞。于是调整门限值 ssthresh cwnd / 2 12 同时设置拥塞窗口 cwnd 1 重新进入慢开始阶段。按照慢开始算法发送方每收到一个对新报文段的确认 ACK 就把拥塞窗口值加 1 。当拥塞窗口 cwnd ssthresh 12 时图中的点 ③这是新的 ssthresh 值改为执行拥塞避免算法拥塞窗口按线性规律增大。 【注】在慢开始阶段若 2 × cwnd ssthresh 则下一个 RTT 后的 cwnd 等于 ssthresh 而不等于 2cwnd 第 16 个轮次时 cwnd 8、ssthresh 12则第 17 个轮次时 cwnd 12 而不等于 16 。 当拥塞窗口 cwnd 16 时图中的点 ④) 出现了一个新的情况就是发送方一连收到 3 个对同一个报文段的重复确认图中记为 3-ACK。关于这个问题要解释如下 有时个别报文段会在网络中丢失但实际上网络并未发生拥塞。如果发送方迟迟收不到确认就会产生超时就会误认为网络发生了拥塞。这就导致发送方错误地启动慢开始把拥塞窗口 cwnd 又设置为 1 因而降低了传输效率。采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失。 在慢开始和拥塞避免算法中使用了“乘法减小”和“加法增大”方法。“乘法减小”是指不论是在慢开始阶段还是在拥塞避免阶段只要出现超时即很可能出现了网络拥塞就把慢开始门限值 ssthresh 设置为当前拥塞窗口的一半并执行慢开始算法。当网络频繁出现拥塞时ssthresh 值就下降得很快以大大减少注入网络的分组数。而“加法增大”是指执行拥塞避免算法后在收到对所有报文段的确认后即经过一个 RTT就把拥塞窗口 cwnd 增加一个 MSS 大小使拥塞窗口缓慢增大以防止网络过早出现拥塞。
2快重传和快恢复
① 快重传算法
采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失快重传算法是使发送方尽快进行重传而不等超时计时器超时再重传。这就要求接收方不要等待自己发送数据时才进行捎带确认而要立即发送确认即使收到了失序的报文段也要立即发出对已收到报文段的重复确认。发送方一旦连续收到 3 个冗余 ACK即重复确认就立即重传相应的报文段而不等该报文段的超时计时器超时再重传。
如下图所示接收方收到了 M1 和 M2 后都分别及时发出了确认。现假定接收方没有收到 M3 但却收到了 M4 。本来接收方可以什么都不做。但按照快重传算法接收方必须立即发送对 M2 的重复确认以便让发送方及早知道接收方没有收到报文段 M3 。发送方接着发送 M5 和 M6 。接收方收到后也仍要再次分别发出对 M2 的重复确认。这样发送方共收到了接收方的 4 个对 M2 的确认其中后 3 个都是重复确认。快重传算法规定发送方只要一连收到 3 个重复确认就知道接收方确实没有收到报文段 M3 因而应当立即进行重传即“快重传”)这样就不会出现超时发送方也不就会误认为出现了网络拥塞。使用快重传可以使整个网络的吞吐量提高约 20% 。 ② 快恢复算法
快恢复算法的原理如下当发送方连续收到 3 个冗余 ACK重复确认时执行“乘法减小”方法把慢开始门限 ssthresh 调整为当前 cwnd 的一半。这是为了预防网络发生拥塞。但发送方现在认为网络很可能没有发生严重拥塞否则就不会有几个报文段连续到达接收方也不会连续收到重复确认。因此与慢开始算法的不同之处是它把 cwnd 值也调整为当前 cwnd 的一半即等于 ssthresh 值然后开始执行拥塞避免算法“加法增大”使拥塞窗口缓慢地线性增大。 注虽然 RFC 5681 给出了根据已发送出但还未被确认的数据的字节数来设置 ssthresh 的新的计算公式即 ssthresh max {FlightSize / 2 , 2 × SMSS} 。这里 FlightSize 是正在网络中传送的数据量。但在讨论拥塞控制原理时我们就采用这种把问题简化的方法即把慢开始门限减半来表述。 因此在下图中的点 ④ 发送方知道现在只是丢失了个别的报文段。于是不启动慢开始而是执行快恢复算法。这时发送方调整门限值 ssthresh cwnd / 2 8 同时设置拥塞窗口 cwnd ssthresh 8见下图中的点 ⑤) 并开始执行拥塞避免算法。 因为跳过了拥塞窗口 cwnd 从 1 起始的慢开始过程所以被称为快恢复。快恢复算法的实现过程如下图所示作为对比虚线为慢开始的处理过程。 【拓展】请注意也有的快恢复实现是把快恢复开始时的拥塞窗口 cwnd 值再增大一些增大 3 个报文段的长度即等于新的 ssthresh 3 × MSS 。这样做的理由是既然发送方收到 3 个重复的确认就表明有 3 个分组已经离开了网络。这 3 个分组不再消耗网络的资源而是停留在接收方的缓存中接收方发送出 3 个重复的确认就证明了这个事实。可见现在网络中并不是堆积了分组而是减少了 3 个分组。因此可以适当把拥塞窗口扩大些。
从上图可以看出在拥塞避免阶段拥塞窗口是按照线性规律增大的这常称为加法增大Additive Increase, AI 。而一旦出现超时或 3 个重复的确认就要把门限值设置为当前拥塞窗口值的一半并大大减小拥塞窗口的数值。这常称为“乘法减小“Multiplicative Decrease, MD。二者合在一起就是所谓的 AIMD 算法。 为什么超时事件发生时 cwnd 被置为1 而收到 3 个冗余 ACK 时 cwnd 减半 大家可以从如下角度考虑。超时事件发生和收到 3 个冗余 ACK 哪个意味着网络拥塞程度更严重通过分析不难发现在收到 3 个冗余 ACK 的情况下网络虽然拥塞但至少还有 ACK 报文段能被正确交付。而当超时发生时说明网络可能已经拥塞得连 ACK 报文段都传输不了发送方只能等待超时后重传数据。因此超时事件发生时网络拥塞更严重那么发送方就应该最大限度地抑制数据发送量所以 cwnd 置为 1 收到 3 个冗余 ACK 时网络拥塞不是很严重发送方稍微抑制一下发送的数据量即可所以 cwnd 减半。 3总结
实际上这四种算法同时应用在 TCP 拥塞控制机制中它们使用的总结在 TCP 连接建立和网络出现超时时采用慢开始和拥塞避免算法ssthresh cwnd / 2, cwnd 1当发送方收到 3 个冗余 ACK 时采用快重传和快恢复算法ssthresh cwnd / 2, cwnd ssthresh。
根据以上所述 TCP 的拥塞控制可以归纳为下图的流程图。 在这一节的开始我们就假定了接收方总是有足够大的缓存空间因而发送窗口的大小由网络的拥塞程度来决定。但实际上接收方的缓存空间总是有限的。接收方根据自己的接收能力设定了接收方窗口 rwnd 并把这个窗口值写入 TCP 首部中的窗口字段传送给发送方。因此接收方窗口又称为通知窗口advertised window。因此从接收方对发送方的流量控制的角度考虑发送方的发送窗口一定不能超过对方给出的接收方窗口值 rwnd 。
即在流量控制中发送方发送数据的量由接收方决定而在拥塞控制中则由发送方自己通过检测网络状况来决定。由于接收方的缓存空间总是有限的因此如果把拥塞控制和接收方对发送方的流量控制一起考虑那么很显然发送方发送窗口的大小由流量控制和拥塞控制共同决定。
当题目中同时出现接收窗口rwnd和拥塞窗口cwnd时发送方发送窗口的上限值应当取为接收方窗口 rwnd 和拥塞窗口 cwnd 这两个变量中较小的一个。也就是说
发送方窗口的上限值 Min [ rwnd, cwnd ]
当 rwnd cwnd 时是接收方的接收能力限制发送方窗口的最大值。 反之当 cwnd rwnd 时则是网络的拥塞程度限制发送方窗口的最大值。 也就是说 rwnd 和 cwnd 中数值较小的一个控制了发送方发送数据的速率。
三、例题
① 在 TCP 协议中发送方的窗口大小取决于 C 。 A. 仅接收方允许的窗口 B. 接收方允许的窗口和发送方允许的窗口 C. 接收方允许的窗口和拥塞窗口 D. 发送方允许的窗口和拥塞窗口
② 以下关于 TCP 窗口与拥塞控制概念的描述中错误的是 C 。 A. 接收窗口rwnd通过 TCP 首部中的窗口字段通知数据的发送方 B. 发送窗口确定的依据是发送窗口 min [接收端窗口拥塞窗口] C. 拥塞窗口是接收端根据网络拥塞情况确定的窗口值 D. 拥塞窗口大小在开始时可以按指数规律增长 【拥塞窗口是发送端根据网络拥塞情况确定的窗口值。】
③ 若甲向乙发起了一条 TCP 连接最大段长为 1KB 乙每收到一个数据段都会发出一个接收窗口为 10KB 的确认段若甲在 t 时刻发生超时此时拥塞窗口为 16KB 。则从 t 时刻起在不再发生超时的情况下经过 10 个 RTT 后甲的发送窗口是 A 。 A. 10KB B. 12KB C. 14KB D. 15KB 【拥塞窗口为 16KB 则新的 ssthresh 8KB 。由于接收窗口为 10KB 发送方窗口的上限值应为拥塞窗口和接收方窗口两个变量中的较小值。】 【因此经过 10 个 RTT 后甲的发送窗口 min [10, 15] 10 。】
④ 设 TCP 的拥塞窗口的慢开始门限值初始为 8单位为报文段当拥塞窗口上升到 12 时发生超时TCP 开始慢开始和拥塞避免则第 13 次传输时拥塞窗口的大小为 C 。 A. 4 B. 6 C. 7 D. 8 【拥塞窗口的大小变化应为1 2 4 8 9 10 11 12 1 2 4 6 7】
⑤ 假设一个 TCP 连接的传输过程在慢开始阶段在 t RTT 时刻到 (t 1) RTT 时刻之间发送了 k 个数据段假设仍然保持在慢开始阶段预期在 (t 1) RTT 时刻到 (t 2) RTT 时刻之间将发送 D 个数据段假设接收方有足够的缓存。 A. k B. k1 C. 2k D. 2k
⑥ 下列关于 TCP 的拥塞控制机制描述错误的是 C 。 A. TCP 刚建立连接进入慢开始阶段 B. 慢开始阶段拥塞窗口指数级增加 C. 超时发生时新门限值慢开始和拥塞避免阶段的分界点等于旧门限值的一半 D. 拥寒避免阶段拥塞窗口线性增加 【超时发生时新门限值通常设置为此时拥塞窗口值的一半而不是旧门限值的一半。】
⑦ 在一个 TCP 连接中MSS 为 1KB 当拥塞窗口为 34KB 时收到了 3 个冗余 ACK 报文。若在接下来的 4 个 RTT 内报文段传输都是成功的则当这些报文段均得到确认后拥塞窗口的大小是D 。 A. 8KB B. 16KB C. 20KB D. 21KB 【条件“收到了 3 个冗余 ACK 报文”说明此时应执行快恢复算法。拥塞窗口的大小变化应为17 18 19 20 21 。】
⑧ 甲向乙发起一个 TCP 连接最大段长 MSS 1KB RTT 3ms乙的接收缓存为 16KB 且乙的接收缓存仅有数据存入而无数据取出则甲从连接建立成功至发送窗口达到 8KB 需经过的最小时间以及此时乙的接收缓存的可用空间分别为 B 。 A. 3ms, 15KB B. 9ms, 9KB C. 6ms, 13KB D. 12ms, 8KB
⑨ 【2009 统考真题】一个 TCP 连接总以 1KB 的最大段长发送 TCP 段发送方有足够多的数据要发送当拥塞窗口为 16KB 时发生了超时若接下来的 4 个 RTT 时间内的 TCP 段的传输都是成功的则当第 4 个 RTT 时间内发送的所有 TCP 段都得到肯定应答时拥塞窗口大小是 C 。 A. 7KB B. 8KB C. 9KB D. 16KB
⑩ 【2010 统考真题】主机甲和主机乙之间已建立一个 TCP 连接TCP 最大段长为 1000B 。若主机甲的当前拥塞窗口为 4000B 在主机甲向主机乙连续发送两个最大段后成功收到主机乙发送的第一个段的确认段确认段中通告的接收窗口大小为 2000B 则此时主机甲还可以向主机乙发送的最大字节数是 A 。 A. 1000 B. 2000 C. 3000 D. 4000 【发送方的发送窗口的上限值取接收窗口和拥塞窗口这两个值中的较小一个于是此时发送方的发送窗口为 min{4000, 2000} 2000B 。因为确认段是对第一个段的确认所以 2000B 的含义是甲发送第一个段后还能再发送 2000B又因为之前甲连续发送了两个最大段也就是说第二个段还未收到确认所以甲还能继续向乙发送的最大字节数是 2000 - 1000 1000B 。】
(11) 【2014 统考真题】主机甲和乙建立了 TCP 连接甲始终以 MSS 1KB 大小的段发送数据并一直有数据发送乙每收到一个数据段都会发出一个接收窗口为 10KB 的确认段。若甲在 t 时刻发生超时的时候拥塞窗口为 8KB 则从 t 时刻起不再发生超时的情况下经过 10 个 RTT 后甲的发送窗口是 A 。 A. 10KB B. 12KB C. 14KB D. 15KB
(12) 【2015 统考真题】主机甲和主机乙新建一个 TCP 连接甲的拥塞控制初始阅值为 32KB 甲向乙始终以 MSS 1KB 大小的段发送数据并一直有数据发送乙为该连接分配 16KB 接收缓存并对每个数据段进行确认忽略段传输延迟。若乙收到的数据全部存入缓存不被取走则甲从连接建立成功时刻起未出现发送超时的情况下经过 4 个 RTT 后甲的发送窗口是 A 。 A. 1KB B. 8KB C. 16KB D. 32KB
(13) 【2017统考真题】若甲向乙发起一个 TCP 连接最大段长 MSS 1KB RTT 5ms 乙开辟的接收缓存为 64KB 则甲从连接建立成功至发送窗口达到 32KB 需经过的时间至少是 A 。 A. 25ms B. 30ms C. 160ms D. 165ms
(14) 【2019 统考真题】某客户通过一个 TCP 连接向服务器发送数据的部分过程如下图所示。客户在 t0 时刻第一次收到确认序列号 ack_seq 100 的段并发送序列号 seq 100 的段但发生丢失。若 TCP 支持快速重传则客户重新发送 seq 100 段的时刻是 C 。 A. t1 B. t2 C. t3 D. t4
(15) 【2020 统考真题】若主机甲与主机乙已建立一条 TCP 连接最大段长MSS为 1KB 往返时间RTT为 2ms 则在不出现拥塞的前提下拥塞窗口从 8KB 增长到 32KB 所需的最长时间是 D 。 A. 4ms B. 8ms C. 24ms D. 48ms
(16) 【2021 统考真题】设主机甲通过 TCP 向主机乙发送数据部分过程如下图所示。甲在 t0 时刻发送一个序号 seq 501、封装 200B 数据的段在 t1 时刻收到乙发送的序号 seq 601 、确认序号 ack_seg 501 、接收窗口 rcvwnd 500B 的段则甲在未收到新的确认段之前可以继续向乙发送的数据序号范围是 C 。 A. 501~1000 B. 601~1100 C. 701~1000 D. 801~1100 【主机甲发送 200B 数据的段后继续发送数据的段的序号 seg 701 。因为甲收到乙发来的确认序号为 501 、接收窗口为 500 的段即从序号 501 开始甲累积还能发送 500B 的数据。因为甲此时已发送从序号 501 开始的 200B 数据所以甲在未收到新的确认段之前还能发送的数据字节数为 500 - 200 300B 还能发送的数据序号范围是 701 ~ 1000 。】
(17) 【2022 统考真题】假设主机甲和主机乙已建立一个 TCP 连接最大段长 MSS 1KB 甲一直向乙发送数据当甲的拥塞窗口为 16KB 时计时器发生了超时则甲的拥塞窗口再次增长到 16KB 所需要的时间至少是 C 。 A. 4 RTT B. 5 RTT C. 11 RTT D. 16 RTT