一、滑窗结构
发送方滑窗可以分为下面两个部分。offered window 为整个滑窗的大小。
接收方滑窗可分为三个部分:
可以看到,接收方的滑窗相对于发送方的滑窗多了一个 " Received; ACKed; Not Sent to Proc " 的部分。接收方接收到的文本流必须等待进程来读取。如果进程正忙于做别的事情,那么这些文本流即使已经正确接收,还是需要暂时占用接收缓存。当出现上述占用时,滑窗的可用部分(也就是图中 advertised window )就会缩水。这意味着接收方的处理能力下降。如果这个时候发送方依然按照之前的速率发送数据给接收方,接收方将无力接收这些数据。
二、流量控制
如果发送端发送太快,导致接收端来不及接收,就容易造成丢失数据。流量控制是指接收方将 advertised window 的大小通知给发送方,从而指导发送方修改 offered window 的大小。接收方将该信息放在TCP头部的 window size 区域:
发送方在收到window size的通知时,会调整自己滑窗的大小,让 offered window 和 advertised window 相符。这样,发送窗口变小,文本流发送速率降低,从而减少了接收方的负担。
三、零窗口
advertised window 大小有可能变为0,这意味着接收方的接收能力降为0。发送方收到大小为0的advertised window通知时,停止发送。
当接收方经过处理,再次产生可用的 advertised window 时,接收方会通过纯粹的 ACK 回复来通知发送方,让发送方恢复发送。然而,ACK回复的传送并不是可靠的。如果该ACK回复丢失,那么TCP传输将陷入死锁(deadlock)状态。
为此,发送方会在零窗口后,不断探测接收方的窗口。窗口探测( window probe )时,发送方会向接收方发送包含1 byte文本流的TCP片段,并等待ACK回复( 该ACK回复包含有window size )。由于有1 byte的数据存在,所以该传输是可靠的,而不用担心ACK回复丢失的问题。如果探测结果显示窗口依然为0,发送方会等待更长的时间,然后再次进行窗口探测,直到TCP传输恢复。
(SAW:Game Over!)