为解决上述问题,我们首先假设每个唯一数据包都有一个序列号,如前所述。我们将数据包窗口定义为数据包的集合(或数据包的序列号),这些数据包已由发送方注入但尚未完全确认(即,发送方尚未收到针对它们的ACK)。我们将窗口大小称为窗口中的包数。术语窗口来自的想法,如果你排队都在一长排的通信会话期间发送的数据包,但只有一小光圈通过它们查看它们,您只会看到它们的一个子集,例如通过窗口进行查看。发送者的窗口(和其他数据包的行)可以用图形表示,如下图所示:
发送方窗口,显示哪些数据包可以发送(或已经发送),哪些数据包没有发送,哪些数据包已经发送和确认。在此示例中,窗口大小固定为三个数据包。
该图显示了三个数据包的当前窗口,窗口总大小为3。3号数据包已经被发送到对端,因此现在可以释放发送端保留的3号的副本。数据包7在发送端已准备就绪,但尚未发送,因为它尚未“在”窗口中。如果我们现在想象数据开始从发送端流向接收端,并且ACK开始反向流动,则发送端可能接下来会收到数据包4的ACK。这种情况发生时,窗口向右“滑动”一个数据包,这意味着可以释放数据包4的副本,并可以发送数据包7。窗口的移动为此类型的协议(滑动窗口协议)产生了另一个名称。
滑动窗口法可用于解决迄今为止描述的许多问题。通常,此窗口结构同时保留在发送端和接收端。在发送端,它跟踪哪些数据包可以释放,哪些数据包正在等待ACK,以及哪些数据包尚未发送。在接收器处,它跟踪已接收和确认了哪些数据包,期望哪些数据包(以及分配了多少内存来保存它们)以及由于内存有限而不会保留哪些数据包(即使已接收) 。尽管窗口结构便于跟踪数据在发送端和接收端之间流动时的便利性,但它并未提供有关窗口应多大的指导,或者如果接收端或网络无法处理发送端的数据速率会发生什么情况,则无法提供指导。现在我们将看到它们之间的关系。
可变窗口:流量控制和拥塞控制
为了解决当接收方相对于发送方太慢时出现的问题,我们引入了一种在接收方无法跟上时强制发送方降低速度的方法。这称为流控制,通常以两种方式之一进行处理。一种方法称为基于速率的流控制,它为发送方提供了一定的数据速率分配,并确保永远不允许以超出分配的速率发送数据。这种类型的流控制最适合流应用程序,并且可以与广播和多播传递一起使用。
流控制的另一种主要形式称为基于窗口的流控制,是使用滑动窗口时最流行的方法。在这种方法中,窗口大小不是固定的,而是允许随时间变化。为了使用此技术实现流量控制,接收者必须有一种方法可以向发送者通知要使用多大的窗口。这通常称为窗口宣告,或简称为窗口更新。发送者(即窗口宣告的接收方)使用此值来调整其窗口大小。从逻辑上讲,窗口更新与上面讨论的ACK是分开的,但是实际上,窗口更新和ACK是在单个数据包中承载的,这意味着发送方在把窗口向右滑动的时候,同时调整其窗口大小。
通过更改发送方窗口大小,我们很清楚这是如何实现流控制的。发送方被允许将W数据包注入网络,然后再听到它们的任何ACK。如果发送方和接收方足够快,并且网络不会丢失任何数据包并且容量无限大,则意味着传输速率与(SW / R)bits / s 成比例,其中W是窗口大小,S是数据包大小(以位为单位),R为RTT。
如果接收方通过发送窗口宣告来控制发送方的窗口大小W时,这个方法的确可以限制发送方的整体发送速率,从而很好的保护了接收方。但是这里没有考虑到发送方和接收方之间的网络连接状况,有可能发送方和接收方通过窗口机制协商了一个互相可以接受的速率,但是中间的网络路由器等设备可能无法负载如此高速率,或者链路带宽不够,拥塞等情况,从而最终导致发送方发送的数据包在中途丢失,解决此问题的方法可以通过一种称为拥塞控制的特殊形式的流量控制来解决。
拥塞控制通过发送方放慢速度,来避免发送和接收方之间的网络过载。在流量控制中,通过使用宣告窗口来告知发送方来控制发送速度,从而减缓接收方的接收速度。这称为显式信令,所谓的显式,既存在一个专门用于向发送方通知发生了什么的协议字段。
同时,也存在另一个选择,那就是让发送者来预测它需要放慢速度。这样的方法将涉及隐式信令,即将基于其他线索和信息来来决定放慢发送速度。