TCP 零窗口后 TCP 重置

sam*_*ba2 6 c sockets printing tcp

多年来,我们的定制软件一直使用打印机命令语言 (PCL) 在不同的打印机上进行打印。

现在我们有一个新的轻型打印机,我们正在努力支持它。简单的打印就可以完美地工作。但是,如果打印作业的大小增大,我们就会遇到打印作业中断的情况。

环境:

  • 两者之间没有活动的网络硬件(例如数据包检查防火墙)。
  • 工作站(这是我们的软件运行的地方)使用 Linux 内核版本 3.0.101。这里发生了下面描述的 TCP 重置。

使用 Wireshark 我们发现以下内容:

  • 我们看到打印机的 TCP 接收窗口大小每 2-3 秒就会变为零。这表明打印机硬件速度太慢,无法实时处理传入数据。
  • 此零窗口超时通常需要大约 1-2 秒。
  • 打印机向工作站发送“零窗口”确认数据包后,工作站尝试通过定期发送 TCP 保持活动数据包来保持与打印机的连接。
  • 打印机正在应答此保持活动数据包。
  • 当打印机准备好再次处理数据时,它会向工作站发送“TCP 窗口更新”数据包。该数据包包含打印机的新接收窗口大小。一旦工作站收到此数据包,它就会开始再次向打印机发送数据。

这是刚刚解释的通信的跟踪片段: 在此输入图像描述

我对“TCP零窗口”机制的理解是,只要打印机正在应答工作站的保活数据包,通信的停止和重新启动就可以永远进行。

然而,在我们的例子中,通信在一段时间后就会中断: 在此输入图像描述

一段时间后(通常是 1-3 分钟后),工作站不再发送新的保持连接,但正在重置通信。对于我们来说,这是无法解释的,因为所有先前的保持活动数据包都会立即被打印机确认。

我也没有成功地尝试复制这个场景。我写了一个简单的TCP客户端和服务器。为了强制出现 TCP 零窗口,TCP 服务器会休眠一段时间,然后继续接收数据。但是,无论服务器等待(睡眠)或中断传输多长时间,我都无法让两者中的任何一个重置通信。相反,上述 TCP 保活/确认算法在空闲时间内运行,以保持连接处于活动状态。

您知道是什么让我们的工作站在有效 TCP 连接期间发送此重置吗?