TCP 在进行0窗口探测的时候,会发送一个字节给接收端,那这个字节会被应用程序读取到吗?

admin 2026-06-30 06:52:26 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档解答了TCP零窗口探测时发送的字节是否会被应用程序读取的问题,指出该字节是重复数据会被接收端丢弃而不会传递给应用层。同时详细解释了避免愚蠢窗口综合征的机制,要求通信双方根据MSS和接收缓冲区大小动态调整窗口更新阈值,确保传输效率。 综合评分: 85 文章分类: 技术标准,网络协议,解决方案


cover_image

TCP 在进行0窗口探测的时候,会发送一个字节给接收端,那这个字节会被应用程序读取到吗?

原创

车小胖谈网络 车小胖谈网络

车小胖谈网络

2026年6月26日 14:48 上海

在小说阅读器读本章

去阅读

看TCP/IP详解的时候,看到下面一段话:

When the persist timer expires, 1 byte of data is sent (segment 6). The receiving application has read 256 bytes from the receive buffer (at time 3.99),so the byte is accepted and acknowledged (segment 7). But the advertised window is still 0, since the receiver does not have room for either one full-sized segment or one-half of its buffer. This is silly window avoidanceby the receiver.

我想问的是这个字节被ACK了,是不是之后要被应用程序读取 ,但这个字节并不是应用程序真正需要的呀!或者有什么方式TCP能做到不会吧这个字节传给应用程序?

不会的!

为何?

因为用于probe的TCP报文这1个byte的数据是duplicated data。

假设A传输给B最后一个byte的序列号为sequence=123456,byte =0xAA

B的接收缓冲区耗尽,于是B紧急发一个window=0的TCP报文给A。

A收到之后立马停止发送,并启动pesist timer,开始倒计时。。。

如果在pesist timer 倒计时到0之前,A收到B的window>0更新,停止并复位pesist timer,A就可以继续发送了。

如果没有收到window更新,pesist timer 响,触发A发送probe报文。

该报文的sequence=123456,byte =0xAA

B收到该报文,发现该序列号对应的数据byte =0xAA已经接收,判断为duplicated。于是丢弃该报文并发送该报文的ACK。

A收到ACK报文如果发现window依然=0,复位pesist timer,继续倒计时,等待下一次的振铃。

A收到ACK报文,如果发现window >0,复位并停止pesist timer,有data就可以发送了。

书中提到的“accepted” +“acknowledged”字眼组合在一起就是上文的描述,accepted并不是真正意义上接受的意思,因为sequence=123456,byte =0xAA这个字节,位于B 的RX方向滑动窗口的左侧,是invalid的,故要丢弃。

上文的“A收到ACK报文,如果发现window >0,复位并停止pesist timer,有data就可以发送了。” 这句话是有问题的!!!

假设B给A的window更新为 window =5,按照上文的说法,A就可以给B发数据了?

如果A要发送5 bytes的数据,需要添加20 bytes的IP、20byte +TCP头,传输效率非常低下,这就是书中提到的silly window

如何silly window avoidance?

通信双方都要严格约束自己。

A要做到的是,如果A发现B的window更新不满足

one full-sized segment or one-half of its buffer

即使window >0 ,也并不发送data。

好抽象,举个例子

1.如果A与B通信协商的MSS = 1448,B握手连接的初始window =4096

那么  min(mss, 0.5 *window) = min(1448, 0.5*4096)=1448

A如果发现B发给自己的window ≥ 1448,才会发送data。

2.如果A与B通信协商的MSS = 1448,B握手连接的初始window =1024

那么  min(mss, 0.5 *window) = min(1448, 0.5*1024) =512

A如果发现B发给自己的window ≥ 512,才会发送data。

这是RFC想要表达的真正的意思,宽以待人,严于律己,即使B犯傻,也不会造成silly window后遗症,只要通信双方有一方不犯傻即可。

RFC同样约束B。

3如果A与B通信协商的MSS = 1448,B握手连接的初始window =4096

那么  min(mss, 0.5 *window) = min(1448, 0.5*4096)=1448

当B的接受缓冲区由于user持续读取data,空闲出了512 byte,能发window update吗?

不能,因为 512 < 1448!

空闲出了1024 byte呢?

依然不能,因为 1024 <1448!

空闲出2000 byte呢?

可以了,因为 2000 > 1448。

4. 如果A与B通信协商的MSS = 1448,B握手连接的初始window =1024

那么  min(mss, 0.5 *window) = min(1448, 0.5*1024) =512

当B的接受缓冲区由于user持续读取data,空闲出了100 byte,能发window update吗?

不能,因为 100 < 512!

空闲出了512 byte呢?

可以了,因为 512 ≥ 512!

任意一方遵守RFC约定,即使另外一方naive,也可以silly window avoidance


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:车小胖谈网络 车小胖谈网络 车小胖谈网络《TCP 在进行0窗口探测的时候,会发送一个字节给接收端,那这个字节会被应用程序读取到吗?》

评论:0   参与:  0