6

我们有一个应用程序服务器,当网络出现拥塞时(在客户端站点),我们观察到它会发送 TCP 窗口大小为 0 的标头。

我们想知道是 Indy 还是底层 Windows 层负责将 TCP 窗口大小从标称的 64K 向下调整以适应可用吞吐量。
我们将能够在它变为 0 时采取行动(什么都没有发送,用户等待 => 不好)。

因此,欢迎任何信息、链接、指向 Indy 代码的指针......

免责声明:我不是网络专家。请让我的答案可以理解;-)
注意:它是 Windows Server 2003 SP2 上的 Indy9/D2007。

更多血腥细节:
TCP 零窗口案例发生在与数据库服务器通信的中间层。
它发生在最终用户抱怨客户端应用程序速度变慢的同一时刻(这就是触发网络调查的原因)。
已确定导致瓶颈的 2 个主要网络问题。
TCP 零窗口是在网络拥塞时发生的,但可能是也可能不是由它引起的。
我们想知道这种情况何时发生,并有办法在我们的代码中做某事(至少记录)。

那么核心问题是谁将窗口大小设置为 0,在哪里设置?
在哪里挂钩(在印地?)知道什么时候发生这种情况?

4

3 回答 3

7

TCP 报头中的窗口大小通常由 TCP 堆栈软件设置,以反映可用缓冲区空间的大小。如果您的服务器发送数据包时窗口设置为零,这可能是因为客户端发送数据的速度比服务器上运行的应用程序读取数据的速度要快,并且与 TCP 连接关联的缓冲区现在已满。

如果客户端发送数据的速度快于服务器读取数据的速度,这对于 TCP 协议来说是完全正常的操作。客户端应避免发送数据,直到服务器发送非零窗口大小(没有意义,因为无论如何它都会被丢弃)。

这可能反映也可能不反映客户端和服务器之间的严重问题,但如果这种情况持续存在,则可能意味着服务器上运行的应用程序已停止读取接收到的数据(一旦开始读取,这将为 TCP 释放缓冲区空间,并且TCP 堆栈将发送一个新的非零窗口大小)。

于 2010-06-08T20:55:51.377 回答
2

窗口大小为零的 TCP 标头表示接收器的缓冲区已满。这是一个比读者更快的作家的正常情况。

在阅读您的描述时,尚不清楚这是否是意外的。是什么导致您打开协议分析器?

于 2010-06-08T20:33:49.313 回答
2

由于您可能也对解决问题的方法感兴趣:

如果您对服务器端正在运行的内容(发送 0 窗口大小消息的那个)有一些控制:您是否考虑过使用带有 SO_RCVBUF 的 setsockopt() 来显着增加套接字接收缓冲区的大小?

在 Indy 中,setsockopt() 是 TIdSocketHandle 的一个方法。您应该将其应用于与您的套接字关联的所有 TIdSocketHandle 对象。在 Indy 9 中,这些是通过 TIdTCPServer 中的属性绑定定位的。

我建议首先使用带有 SO_RCVBUF 的 getsockopt() 来查看操作系统为您提供的默认缓冲区大小。然后显着增加这一点,可能是通过连续试验,每次增加一倍的大小。您可能还希望在您的 setsockopt()之后重新运行 getsockopt() 调用,以确保您的 setsockopt 已实际执行:套接字实现通常设置缓冲区大小的上限。在这种情况下,通常有一种依赖于操作系统的方法来提高上限。但这些都是相当极端的情况,你不太可能需要这个。

如果您无法控制溢出一侧的源代码,只需检查那里运行的软件是否公开了一些参数来更改缓冲区大小。

祝你好运!

于 2010-06-10T07:10:07.660 回答