4 滑动窗口机制
4.1 可靠传输的工作原理
TCP发送的报文段是交给IP层传送的。但IP层只能提供尽最大努力服务,即,TCP下面的网络所提供的是不可靠的传输。
理想的传输条件:
- 传输信道不产生差错
- 不管发送方以多块的速度发送数据,接受方总是来得及处理收到的数据
为了实现可靠性传输,需要考虑很多事情,例如数据的破坏、丢包、重复以及分片顺序混乱等问题。如不能解决这些问题,也就无从谈起可靠传输。
TCP 是通过序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输的。
首先使用一些可靠传输协议,当出现差错的时候让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的速率。
最简单的可靠传输协议即停止等待协议。
4.1.1 停止等待协议
全双工通信的双方既是发送方也是接收方。这里假设仅考虑A是发送方,B是接收方。
①无差错情况
如上图a,A发送分组M,发完就暂停发送,等待B的确认。B收到之后向A发送确认,A收到确认之后,再发送下一个分组。
②出现差错(超时重传)
B接收M1时出现了差错,就丢弃M1,但是什么也没做,不发送任何信息。 A只要超过了一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重新传送前面发送过的分组,这个过程叫做超时重传。
实现超时重传,就要设置一个超时计时器,如果在超时计时器到期之前收到了对方的确认,就撤销已经设置的超时计时器。
注意事项:
1)A在发送完一个分组之后,必须暂时保留已发送的分组副本。受到相应的确认之后,再清楚暂时保留的分组副本。
2)分组和确认分组都必须编号。这样才能明确哪一个分组还没收到确认。
3)超时计时器设置的时间应该比数据在分组传输的平均往返时间更长一些。
如果超时重发的数据,再次超时的时候,又需要重传的时候,TCP 的策略是超时间隔加倍。
也就是每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。
③确认丢失和确认迟到
即B所发送的对M1的确认丢失了。A在超时重传的时间内没有收到确认,但无法知道是自己发送的分组出错、丢失,还是N发送的确认收到丢失了。因此A在超时计时器到期后重传M1,B又收到重传的分组M1之后,首先丢弃这个重复的M1,其次向A发送确认。
通过上述这种确认和重传机制,就可以在不可靠的传输网络上实现可靠的通信,这种协议常被称为自动重传请求ARQ。意思是重传的请求是自动进行的,接收方不需要请求发送发重传某个出错的分组。
停止等待协议比较简单,但是信道利用率太低了。
改进:不使用停止等待协议,而是使用流水线传输。
发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。
由于信道上一直有数据不间断地传送,这种传输方式可获得很高的信道利用率。
使用流水线传输时,就要用到连续ARQ协议和滑动窗口协议。
4.1.2 连续ARQ协议
TCP 引入了窗口这个概念。即使在往返时间较长的情况下,它也不会降低网络通信的效率。
那么有了窗口,就可以指定窗口大小,窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。
窗口的实现实际上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。
假设窗口大小为 3 个 TCP 段,那么发送方就可以「连续发送」 3 个 TCP 段,并且中途若有 分组丢失,可以通过「下一个确认应答进行确认」。
图中的 ACK 600 确认应答报文丢失,也没关系,因为可以通过下一个确认应答进行确认,只要发送方收到了 ACK 700 确认应答,就意味着 700 之前的所有数据「接收方」都收到了。这个模式就叫累计确认或者累计应答。
TCP 头里有一个字段叫 Window ,也就是窗口大小。
这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。
所以,通常窗口的大小是由接收方的窗口大小来决定的。发送方发送的数据大小不能超过接收方的窗口大小,否则接收方就无法正常接收到数据。
4.1.3 超时时间的设置
我们先来了解一下什么是 RTT (Round-Trip Time 往返时延),从下图我们就可以知道:
RTT即为数据从网络一端传到另一端所需的时间。
超时重传时间是以 RTO (Retransmission Timeout 超时重传时间)表示。
假设在重传的情况下,超时时间 RTO 「较长或较短」时,会发生什么事情呢?
上图中有两种超时时间不同的情况:
- 当超时时间 RTO 较大时,重发就慢,丢了老半天才重发,没有效率,性能差;
- 当超时时间 RTO 较小时,会导致可能并没有丢就重发,于是重发的就快,会增加网络拥塞,导致更多的超时,更多的超时导致更多的重发。
精确的测量超时时间 RTO 的值是非常重要的,这可让我们的重传机制更高效。
根据上述的两种情况,我们可以得知,超时重传时间 RTO 的值应该略大于报文往返 RTT 的值。
实际上「报文往返 RTT 的值」是经常变化的,因为我们的网络也是时常变化的。也就因为「报文往返RTT 的值」 是经常波动变化的,所以「超时重传时间 RTO 的值」应该是一个动态变化的值。
需要注意:
如果超时重发的数据,再次超时的时候,又需要重传的时候,TCP 的策略是超时间隔加倍。
也就是每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。
超时触发重传存在的问题是,超时周期可能相对较长。那是不是可以有更快的方式呢?
于是就可以用「快速重传」机制来解决超时重发的时间等待。
4.1.4 快速重传
TCP 还有另外一种快速重传(Fast Retransmit)机制,它不以时间为驱动,而是以数据驱动重传。