TCP流量控制

114 阅读2分钟

前言

TCP连接的接收方会设置一个 接收缓存 ,当TCP连接收到正确、按序的字节后,就将数据放入接收缓存

这时,如果接收方读取数据相对较缓慢,而发送方发送太多、太快,就会导致接收方的接收缓存溢出

因此,TCP提供一个流量控制控制服务,以消除发送方使接收方缓存溢出的可能性

流量控制因此是一个速度匹配服务,即发送发的发送速率和接收方应用程序的读取速率相匹配

接收窗口

TCP通过让发送方维护一个称为接收窗口的变量来提供流量控制

接收窗口用于给发送方一个提示:该接收方还有多少可用的缓存空间

假设情况

假设A向B发送一个文件,设B的接收缓存大小为 RcvBuffer

B的应用进程不时地从该缓存中读取数据

我们定义以下变量:

  • LastByteRead:主机B上的应用进程从缓存读出的数据流的最后一个字节的编号
  • LastByteRcvd:从网络中到达的并且已放入主机B接收缓存中的数据流的最后一个字节的编号

为了不使缓存溢出,我们需要满足:

			LastByteRcvd - LastByteRead <= RcvBuffer

接收窗口的大小,是动态的

			rwnd = RcvBuffer - [ LastByteRcvd - LastByteRead]

综上,我们只要控制未确认的数据量在rwnd以内即可(就是主机A已经发送到TCP连接中,但未被确认的数据量小于接收窗口的大小)

			 [LastByteRcvd - LastByteRead] <= rwnd

如果在某一时刻,rwnd=0,即接收缓存已经满时,B告诉A已经满了,但是如果一段时间后B读取完接收缓存的数据后,接收缓存有了新的空间,但是A不会接收到这个通知!

因为事实上,TCP仅当在它有数据或有要确认要发时才会发送报文段给主机A,这样的话A不可能知道主机B的接收缓存已经有新的空间

这时就会造成阻塞: A在等B的新空间,B在等A发新数据

解决方法:

  • TCP为每一个连接设有一个持续计时器(persistence timer),只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器

  • TCP要求:当主机B的接收窗口为0时,若持续计时器设置的时间到期,主机A就继续发送只有一个字节数据的报文段,这些报文段会被接收方确认,最终缓存开始清空,并且确认报文里将包含一个非0的rwnd值