TCP必须能处理打开窗口ACK丢失的情况。ACK的传输并不可靠,也就是说,TCP不对ACK报文进行确认,TCP只对那些包含数据的ACK报文段进行确认。
如果一个确认丢失了,则双方可能因为等待对方而使连接终止:接收方等待接收数据(它已经向发送方通告了一个非0的窗口),而发送方在等待允许它继续发送数据的窗口更新。为防止这种死锁情况发生,发送方使用一个坚持定时器来周期性的向对方查询,以便发现窗口是否已增大。这些从发送方发送的报文段称为窗口探查
1.坚持定时器
当接收方通告窗口为0时,客户停止发送任何其他数据。这就引起客户设置其坚持定时器。如果在该定时器时间到时客户还没有接收到一个窗口更新、它就探查这个空的窗口以决定窗口更新是否丢失。
计算坚持定时器时使用了普通的TCP指数退避。
窗口探查包含了一个字节的数据。所返回的窗口为0的ACK并不是确认该字节,因此这个字节被持续重传。
坚持定时器与重传定时器不同在于TCP不放弃发送窗口探查。这些探查每隔60秒发送一次,这个过程将持续或者窗口被打开,或者应用进程使用的连接被终止
2.糊涂窗口综合症
接收方可以通告一个小窗口(而不是一直等到有大的窗口时才通告),而发送方也可以发送少量的数据(而不是等待其他的数据以便发送一个大一点的报文段)。
可以再任何一段采取措施避免出现糊涂窗口综合症的现象
1.接收窗口不通告小窗口。通常的算法是不通告一个比当前窗口大的窗口,除非窗口可以增加一个报文段的大小或者可以增加接收方缓存空间的一半,不论实际是多少。
2.发送方只有满足以下条件之一才发送数据:
·可以发送一个满长度的报文段
·可以发送至少是接收方通告窗口大小一半的报文段
·可以发送任何数据并不希望接受ACK(也就是还没有未被确认的数据)或者该连接上不能使用Nagle算法
每次当应用程序从TCP的接受缓存中读取数据时,接收的TCP将检查是否需要更新发送窗口