作者回复: “ack的行为跟应用层是否收这个数据无关”--这是正确的,也就是TCP不需要等应用层取走数据后再给发送端给与TCP确认。不过,应用层收取数据太慢的话,事实上会导致接收缓冲区变大,容易触及分配给这个socket的缓冲区上限。到达上限的时候,就是发送windows=0的时候了~ 另外,我在t3这里标记了“window full”,这是wireshark的解读,并不是tcp报文本身携带的信息。接收方接收窗口是1000,收到了1000,那么此时窗口用完了,这是一种判断。它跟zero window是不同的。 window full:在途数据=接收窗口,是wireshark的解读 zero window: 明确的在报文里window字段是0,不需要wireshark也可以直接看出来,比如在tcpdump的输出里
作者回复: 在途字节数700字节,是发送端自己判断出来的,是根据“已发送数据 - 被确认数据”得出的。 而Window Full是Wireshark根据报文情况作出的解读,这个信息表示:在被标记的时间点,(服务端的)接收窗口已经被用完。这里不会有丢弃的行为。 在服务端确认了300字节的数据后,发送端就知道,虽然另外700字节还未被确认(因此仍属于在途数据),但是窗口已经空出了300字节了,于是可以继续发送300字节。 在服务端应用程序从缓冲区取走更多数据后,发送端就可以发送更多字节。 概括来说,在TCP里,发送端是不会发出超过对方缓冲区大小的数据的(恶意的除外)。
作者回复: 正好有个学员也问到了zero window的问题,我把问题和回复都在这里发一下,供你参考: 问:老师,我们工作中有同事遇到了tcp window zero,我当时没参与这个任务,没去看具体的抓包数据,但好像也是接收端窗口满了的原因。请问window zero 和window full的区别是什么呢?是视角不同吗?zero是接收端视角,full是发送端视角? 作者回复: 你好,这两个信息都是关于window的,确实很容易搞混,我这里解释一下。其实跟视角没关系。 tcp window zero是指,这个tcp报文的window字段明确就是0,也就意味着这个报文的发送方的接收缓冲区已经变成0了,另一方就会停止发送数据。当然,为了避免无限等待,另一方会有探测机制,定制发送一个零载荷的报文,让window zero这一端回复报文,从这个回复报文里读取到最新的window值。 tcp window full是指,这个报文发送后,另一端的接收窗口就满了。我举个例子,现在A和B在通信,A的一个报文被wireshark标记为tcp window full,指的是A的未被确认的数据量(也就是在途字节数)跟B的接收窗口相等。这意味着A不会发送更多报文(即使B没有发送window zero的报文),因为A知道发送出去的数据量已经“填满”了B的接收缓冲区~