TCP通过让发送方维护一个接收窗口来给发送方指示出接收方还有多少可用的缓存空间
假设A给B发送一个大文件
现定义以下变量
LastByteRead:主机B上的应用进程从缓存读出的数据流的最后一个字节的编号
LastByteRcvd:网络中已经到达并且已经放入主机B的接收缓存中的数据流的最后一个字节的编号
RcvBuffer:B的接收缓存大小
则需要满足以下条件:
LastByteRcvd - LastByteRead ≤ RcvBuffer
rwnd = RcvBuffer - [ LastByteRcvd - LastByteRead ]
所以,rwnd是动态的
主机B告诉A的接收窗口指的是什么?
指的是rwnd,主机B通过把rwnd的值放到它给A的报文段的接收窗口字段中,就可以告诉A它在该连接的缓冲中还有多少可用空间
那么主机A如何根据B给的rwnd来进行发送调整呢?
主机A轮流跟踪2个变量,LastByteSent(最后发出报文的序号)和LastByteAcked(最后收到的报文的确认序号)
这2个变量的差LastByteSent - LastByteAcked,就是主机A发送到连接中但未被确认的数据量,通过将未确认的数据量控制在rwnd内,就可以保证主机A不会使主机B的接收缓存溢出
方案所存在的问题
假设主机B的接收缓存已经满了,则rwnd = 0,在将rwnd通报给A后,B已经没有任何数据要发给A了,过一阵子B缓存被清空了,可以继续接收报文了,但由于B已经没有报文要发给A了,并不会向A发送rwnd ≠ 0的报文,所以A会一直无限等下去,这样就造成死锁
怎么解决?
引入了持续计时器(Persistence timer),当A收到对方的零窗口通知时,就启用该计时器,时间到则发送一个1字节的探测报文,对方会在此时回应自身的接收窗口大小,如果结果仍未0,则重设持续计时器,继续等待