(21)TCP的超时和重传
一、简介
TCP提供可靠的传输层。使用的方法之一是确认从另一端收到的数据,但数据和确认都有可能会丢失。TCP通过设置定时器和重传策略来解决这种问题。
TFTP客户使用UDP时限了一个简单的超时和重传机制:5秒作为定时器值,每隔5秒进行重传;另外,向一个不存在的主机主机发送ARP,当TCP试图建立连接的时候,在每个重传之间使用一个较长的时延来重传SYN。
对每一个连接,TCP管理4个不同的定时器:
(1) 重传定时器用于当希望收到另一端的确认。
(2) 坚持定时器使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口。
(3) 保活定时器可检测到一个空闲连接的另一端何时崩溃或重启。
(4)2MSL定时器测量一个连接处于TIME_WAIT状态的时间。
二、往返时间测量
TCP超时和重传重最重要的就是对一个给定连接的往返时间(RTT)的测量。由于路由器和网络流量均会变化,因此TCP应该跟踪这些变化并相应地改变超时时间。首先TCP必须测量在发送一个带有特别序号地字节和接收到包含该字节地确认之间的RTT。
三、拥塞避免算法
拥塞避免算法是一种处理丢失分组的方法。该算法假定由于分组受到损坏引起的丢失是非常少的(远小于1%),因此分组丢失就意味着在源主机和目的主机之间的某处网络上发生了阻塞。
有两种分组丢失的指示:发生超时和收到重复的确认。
拥塞避免算法需要对每个连接维持两个变量:一个拥塞窗口cwnd和一个慢启动门限ssthresh。
(1) 对一个给定的连接,初始化cwnd为1个报文段,ssthresh为65535个字节。
(2) TCP输出例程的输出不能超过cwnd和接收方通告窗口的大小。拥塞避免是发送方使用的流量控制,而通告窗口时接收方进行的流量控制。前者是发送方感受到的网络拥塞的估计,而后者则与接收方在该连接上的可用缓存大小有关。
(3) 当拥塞发生时,ssthresh被设置为当前窗口大小的一半(cwnd和接收方通告窗口大小的最小值,但最小为2个报文段)。此外,如果是超时引起了拥塞,则cwnd被设置为1个报文段。
(4) 当新的数据被对方确认时,就增加cwnd,但增加的方法依赖与是否正在进行慢启动或拥塞避免。如果cwnd小于或等于ssthresh,则正在进行慢启动,否则正在进行拥塞避免。
拥塞避免算法要求每次接收到一个确认时将cwnd增加1/cwnd。与慢启动的指数增加比起来,这是一种加性增长。我们希望在一个往返时间内最多为cwnd增加1个报文段,然而慢启动将根据这个往返时间中所收到的确认的个数增加cwnd。
四、快速重传和快速恢复算法
如果我们一连串收到3个或以上的重复ACK,就非常可能是一个报文段丢失了。于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。这就是快速重传算法。接下来执行的不是慢启动而是拥塞避免算法,这就是快速恢复算法。
这个算法通常按如下过程实现:
(1)当收到第3个重复的ACK时,将ssthresh设置为当前拥塞窗口cwnd的一半,重传丢失的报文段,设置cwnd为ssthresh加上3倍的报文段大小。
(2)每次收到另一个重复的ACK时,cwnd增加1个报文段大小并发送一个1个分组,如果新的cwnd允许发送。
(3)当下一个确认新数据的ACK到达时,设置cwnd为ssthresh,这个ACK应该是在进行重传后的一个往返时间内对步骤1中重传的确认。另外,这个ACK也应该是对丢失的分组和收到的第一个重复的ACK之间的所有中间报文段的确认。
五、ICMP差错
TCP如何处理一个给定的连接返回的ICMP差错。TCP能够遇到的最常见的ICMP差错就是源站抑制、主机不可达和网络不可达。
(1)一个接收到的源站抑制引起拥塞窗口cwnd被置为1个报文段大小来发起慢启动,但是慢启动门限ssthresh没有变化,所以窗口将打开直到它开放了所有的通路或者发生了拥塞。
(2)一个接收到的主机不可达或网络不可达实际都被忽略,因为这两个差错都被认为是短暂现象。TCP试图发送引起该差错的数据,尽管最终有可能会超时。
六、重新分组
当TCP超时并重传时,它并不一定要重传同样的报文段,相反,TCP允许进行重新分组而发送一个较大的报文段。在协议中这是允许的,因为TCP是使用字节序号而不是报文段序号来进行识别它所要发送的数据和进行确认。