TCP-数据流与窗口管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010853261/article/details/82251168

前面两篇文章介绍了TCP的连接与断开;TCP利用丢失数据的重传来保障传输的可靠性。下面主要讨论动态数据传输。后面还会讨论TCP的流量控制机制,通过动态调节窗口大小来控制发送端操作确保接收端不会溢出,该思路也可以应用于其余实际问题。

  1. 交互式通信
  2. 延时确认
  3. Nagle算法
  4. 流量控制与窗口管理

4.流量控制与窗口管理

前面已经多次提到,TCP采用可变滑动窗口来实现流量控制。如下图,TCP的客户端和服务端的交互互相提供数据流相关元信息,包括:报文段序列号、ACK号和窗口大小(接收端的可用空间)
这里写图片描述

上图中两个大的箭头代表数据流的方向(TCP)报文传输方向,每个TCP都是双向连接,这里用两个箭头表示。每个报文段都包含ACK和窗口信息,可能还有用户数据。每个TCP报文段(除了连接建立之初的包交换)都包含一个有效的序列号字段、一个ACK号或确认字段以及一个窗口大小字段(窗口通告)。

每个TCP报文里面的头部的窗口大小字段表明接收端可以使用的缓存空间大小,该字段是16位的所以窗口最大为65535个字节,但是窗口缩放选项可以用于大于65535的值。 报文段发送方在相反方向上可以接收的最大序列号值是TCP头部中的ACK号和窗口大小字段之和。

4.1 滑动窗口

TCP连接的每一段都可以接收和发送数据,收发端都是通过一组窗口接口来维护的。每个TCP活动连接的两端都维护一个发送窗口和接收窗口。下图展示了一个假设的TCP发送窗口结构:

这里写图片描述

TCP以字节而不是数据包的单位为维护其窗口结构。 上图主要是将边界分为四个区域:已发送并发送确认、已发送未确认、即将发送、窗口移动前都不能发送。随着时间的推移当接收到ACK时候滑动窗口也随之右移。窗口两端的相对运动导致窗口的增大或则减小,可用三个术语概念来描述窗口左右边界的运动:
1)关闭:即左边界右移,当已发送数据收到ACK时,窗口会变小
2)打开:即右边界右移可使得发送数据量编大。当已确认数据得到处理,接收端可用缓存变大,窗口也随之变大。
3)收缩:即窗口右边界左移,这种场景很少。

从TCP报文结构我们可以知道,每个TCP报文段都包含ACK号以及窗口通告信息,TCP据此调节窗口结构(调整的起始是左右边界)。有一种需要特别关注的状态:当左右边界相等时,我们就称为零窗口,此时发送端将不能再发送新数据,这种情况下TCP发送端开始 探测 对方窗口,伺机增大提供窗口。

TCP接收端也维护着一个窗口接口,不过比发送端结构简单。如下图所示:

这里写图片描述

该窗口记录了:已接受不并确认的数据、接收窗口、以及不能接收窗口。接收窗口还记录了它能接收的最大序列号,该窗口可以确保其接收数据的正确性,特别是接收端希望避免存储重复的已接收和确认的数据以及避免存储不应接收的数据(超过窗口右边界的数据)

对于接收端来说:到达的序列号小于窗口左边界被认为是重复数据而丢弃,超过右边界的则认为超出处理范围也被丢弃。 由于TCP的累积ACK结构,只有当到达数据序列号等于左边界时,数据才不会被丢弃,窗口才能向前滑动。对于选择确认TCP来说,使用SACK选项,窗口内其余报文段也可以被接收确认,但是只有在接收到等于左边界的序列号数据时,窗口才能迁移(SACK更多细节参考前一篇文章)。

4.2 零窗口与TCP持续计时器

前面已经说了TCP以接收端的窗口通告来进行流量控制。窗口通告指示了接收端可接受的数据量。当窗口值变为0的时候,可以有效的阻止发送端继续发送数据,直到窗口大小恢复到非零。 当接收端有可用窗口的时候会给发送端发送一个纯的窗口更新告知其可以继续发送数据。但是这样的窗口更新通常都不包含数据(纯ACK),不能保证其传输的可靠性,所以TCP必须能cover住这块数据包的丢包情况。

考虑这样一种情况:一个纯的窗口更新ACK丢包了,通信的双方会一直处于等待状况:接收方等待接收数据,发送方等待接收窗口更新ACK才可继续发送方数据。为防止这种死锁的发生,发送端会采用一个 持续计时器 间歇性的查询接收端,看其窗口是否已经增长。 持续计时器会触发窗口探测的传输,强制要求接收端返回ACK(包含可用窗口大小)。

窗口探测(一种数据段)包含一个字节的数据,采用TCP可靠传输(丢失重传),因此避免由于窗口更新丢失导致的死锁。当TCP持续计时器超时就会触发窗口探测的发送。其中一个字节的数据能否被接收取决于接收端缓存的大小。

与TCP重传计时器类似,也可以采用指数时间退避来计算持续计时器的超时。不同之处在于TCP不会停止发送窗口探测,由此可能会放弃执行重传操作。

4.3 糊涂窗口综合征

基于窗口流量控制机制,尤其是使用数据报大小不固定的协议,可能会出现糊涂窗口综合征(SWS)。该问题主要现象就是:数据报中有用数据相对于头部信息比例较小,因此耗费资源比较多,传输效率低。

TCP的两端都可能造成SWS:接收端的通告窗口较小(没等到窗口变大才通告)或则发送端发送的数据段较小(没有等到其余数据组合成更大的数据报再发送)。 要避免SWS问题,就必须要在收发段实现相关规则:

1)对于接收端来说:不应该通告小的窗口值

2)对于发送端来说:不应发送小的报文段,并且需要有Nagle算法控制何时发送。要避免SWS。至少满足下面条件之一才发送:
a)全长(MSS字节)的报文段可以发送
b)数据段长度>=接收端通高过的最大窗口值的一半才可以发送
c)满足以下任何一个都可以发送:i)某一个ACK不是目前期盼的(没有经过确认的在传输数据);(ii)连接禁用了Nagle算法。

条件a直接避免了高耗费的报文传输问题;条件b针对通告窗口值较小,可能小于要传输的报文段情况。请情况c防止TCP在数据需要被确认以及Nagle算法启用情况下发动小报文段。

4.4 大容量缓存与自动调优

主要是TCP的缓存不可设置,系统会自动根据连接传输带宽延时等值实时改变接收窗口的缓存。

自动调优受限制与缓存的大小。

猜你喜欢

转载自blog.csdn.net/u010853261/article/details/82251168