TCP机制下为什么要同时拥有滑动窗口和拥塞控制窗口?

一、Flow Control 的机制

想象一下有两个host,host A和host B,它们现在通过TCP connection连接在一起,开始互相传数据。在这个connection的两端,也就是A和B上,都有一个receive buffer,从网络上来的数据(bytes)如果是正确且有序的,那么就会先放入到receive buffer里,然后在被host的应用层读取。注意,应用层读取数据并不是即时的,这意味着数据会在receive buffer里积压,如下图。



我们来假设一个比较极端的情景。现在A以一个很高的transmission rate向B传一个大文件,同时B的应用层从receive buffer里读取数据的速度很慢。这样的结果就是B的receive buffer很容易就overflow了。Flow control的目的就是在于防止这一情况的出现,即在这个例子里,不让A去overflow B的receive buffer。简单来说,flow control提供一个速度匹配(speed-matching)机制,即令host A发送数据的速度和host B读取数据的速度匹配,从而避免overflow的情况发生。同时,由于TCP是full-duplex的,所以这个机制是双向的。

overflow的坏处是什么呢?直接的后果就是数据会丢失,从而降低整个网络的传输效率。放到城市规划的领域来类比,就是两个路口A和B之间有一段路,而从路口B到路口A的交通流超过了一个路口A的通行能力,而车流还在源源不断地从路口B涌向路口A,最终导致AB路段的交通堵塞。

那么TCP是如何实现flow control的呢

概括而言,主要为以下几个要点:

  1. sender维护一个变量,这个变量叫做receive window,即,rwnd,记录receive buffer的剩余空间;
  2. sender还会维护另外两个变量,分别叫做LastByteSentLastByteAcked
  3. receiver维护两个变量,叫做LastByteReadLastByteRcvd;

其中,LastByteRead是receiver的应用层最近一次从receive buffer里读走的数据的byte数量,而LastByteRcvd则是receiver最近一次从网络收到的数据的byte数量。

同时,在TCP connection建立的时候,两边的host都会分配一个receive buffer,其大小用RcvBuffer表示。

TCP协议不允许overflow receive buffer,所以必须满足:


本质上讲,flow control的实现就是,receiver把自己的buffer还剩下多少空间以值rwnd的形式发回给sender,然后sender通过比较三个值:rwnd, LastByteSent和LastByteAcked之间的关系来控制自己发送数据的速度。即要满足以下关系:


如果继续沿用前边的例子的话,就是host B把rwnd的值放在transport layer segment的receive window 这个字段里发回给host A,然后host A通过比较上述三个值,来保证那些“还在路上”的数据数量是小于等于host B的receive buffer的剩余空间的。

现在,路口A和路口B之间增加了通信功能,路口B在还没有发生拥堵的时候,会向路口A发送信息,告诉它大概再来几辆车可能就要堵住了。这时候路口A就会开始限制通行的汽车的数量,从而保证在路段AB内的车始终可以比较通畅地通行。

这个过程用流量图来表示如下:



这里省略了一个技术细节,就是上图"read 2k to upper layer"那里。严格来说receiver不会主动发送这个信息给sender,而是sender在上一次知道rwnd为0之后会持续不断地发送1byte的数据包给receiver,这样当receive buffer又有空间的时候新的rwnd值就可以传给sender了。

以上就是flow control的机制。为了不要与后边的congestion control搞混,需要特别注意的是,虽然sender会维护一个叫做rwnd的变量,但是这个receive window实际上是在receiver端的,之所以sender可以得到这个值,是因为receiver会以把这个值放到传给sender的数据包里的方式让sender知道而已

二、Congestion Control 的机制

在flow control的基础上理解congestion control就比较容易了。

首先,congestion control的“官方定义“是这样子的:

控制sender向connection传输数据的速率,使这个速率为网络拥堵状况的函数

核心的关键词:网络拥堵状况的函数,网络拥堵状况的函数,网络拥堵状况的函数,重要的事情强调三遍。

什么意思呢?就是sender发送数据的速率不仅要考虑receiver的buffer(flow control负责的事情),还要考虑网络状况。下面继续沿用前边交通的例子:

经过flow control之后,路口A和路口B之间的拥堵状况消失了。但是,天有不测风云,路段AB之间的某一处发生了一起车祸,本来4车道现在只有1条车道能用了,导致通行能力收到的极大的限制。这个时候虽然路口B远没有达到塞车的阈值,但是车开始堵在路段中间的某个位置了。这个时候,显然,路口A不能再按照原来的速率允许车从路口A进入AB路段了。

这就在sender端要维护一个congestion window,即cwnd的原因。cwnd如下图:


sender发送数据之后,会收到receiver的ack,如果总是收不到ack,而rwnd显示receive buffer还没有满,那么就说明是channel的问题,这个时候必须降低发送速率,否则依然会出现数据包的丢失情况。

三、为什么不多余

其实看到这里,事情已经很明显了。那就是flow control和congestion control两者是相辅相成的。即,sender的发送速率要满足:

从而分别从sender和receiver两端来保证通信的通畅。所以题目中说两者等同是不准确的。

至于congestion control的几个阶段,譬如slow start,congestion avoidance和fast recovery就不是题主关注的重点了,在此略过。



  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值