设备 1 Windows XP。192.168.101.173,我可以访问应用程序代码,但它太大了。
设备 2 嵌入式设备。192.168.101.205。我无法访问此设备的代码,甚至无法访问其日志。
设备 1 和设备 2 已连接,但设备 2 显然不支持 SACK。因此,我想在第一个设备上禁用 SACK,看看我遇到的问题是否得到解决。
以下是 Wireshark 上发生的一些情况。请注意,该图片仅用于说明目的,并非用于发送我所面临的问题的数据。
可以看出,第一台设备发送重启连接命令,之后发送 SACK。第二台设备从此无法恢复。
更新:两台设备之间的通信流量并不大,而是第二台设备上的持续 ping,不时出现大量数据流,但数据量在 KB 范围内,除此之外,通信只是前面提到的 ping,所以看到这么多 SACK 真的很烦人。我不知道在 Windows 端禁用 SACK 是否能解决任何问题,但我想看看停用它们后系统的行为。
更新:请查看 Wireshark 捕获的正在发生的事情此链接。文件上的简短评论:11:35 我休息了一下。11:53 我重新开始捕获。到这里一切都正常。在包 963 处,设备 2 上的应用程序发生了一些事情。显然,它冻结了。您可以看到设备 2 不会重放,它只会发送 ACK(与它所做的 ACK 然后回答不同)。
在包 969 处设备 1 重置连接。
从那里您可以不断看到 SACK_PERM。所以我想在 Windows XP 机器上禁用 SACK,看看是否有任何改进。
回答之前,请再读一遍问题。
答案1
Windows 中的 SACK 支持通过注册表控制:
- 钥匙:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
- 价值:
SackOpts
- 类型:REG_DWORD
- 数据:0 表示禁用
SACK 不是唯一使用 TCP 选项的功能;TCP1323Opts
控制时间戳和窗口缩放,并且我认为没有任何方法可以禁用“最大段大小”选项。
参考:https://www.fs-net.de/assets/download/docu/netdcu/en/NetDCU_TCPIP_ParametersConfigurableByUser.pdf
从那里您可以不断看到 SACK_PERM。所以我想在 Windows XP 机器上禁用 SACK,看看是否有任何改进。
不太可能。
首先,“SACK_PERM”不是 SACK 的实际用途——“SACK_PERM”就是 SACK能力协商,TCP 握手选项,表示如果对方同意,则愿意使用 SACK。不支持 SACK 的设备只会应答握手而不包含其自己的“SACK_PERM”选项,并且连接将自动继续,而无需使用 SACK。
但是,您的设备做在其答案中包含“SACK_PERM”,表明它确实支持 SACK– 不仅如此,它还会在发送的数据包中生成实际的 SACK(例如您捕获的数据包 954)。因此,这推翻了您最初的猜测,即设备 2 不支持 SACK,这意味着在客户端禁用 SACK 不太可能产生任何有用的效果。
(您所描述的“恒定的 SACK_PERM”并不是 SACK 使用情况的样子;它更像是当设备 1 不断尝试建立新连接时“恒定的 TCP 握手尝试”,尽管 Wireshark 在其 GUI 中强调了这一点,但 SACK 提供不是主要内容这些数据包。)
即使设备的内存空间非常紧张,无法实现 SACK,它也可以仍然能够接受带有选项的 TCP SYN,而忽略它不理解的选项,因为过去 35 多年来,几乎每个操作系统都在每次握手中添加了这些选项——任何制造商生产需要在每个客户端中全系统禁用 SACK 的设备都是不现实的。
此外,不仅仅是SACK使用 TCP 选项;它也是 TCP 窗口大小缩放;TCP MSS 协商;TCP 时间戳......从包含所有这些选项的 SYN_ACK 回复来看,您的设备显然可以很好地支持所有这些。
其次,在您的描述中:
在包 963 处,设备 2 上的应用程序发生了一些事情。显然,它冻结了。您可以看到设备 2 没有重放,它只发送了一个 ACK(与它所做的 ACK 然后回答不同)。
在包 969 处设备 1 重置连接。
…不是同一个连接。这些数据包是针对不同的 TCP 端口号发送的。
tcp.stream eq 4
据我在捕获中看到的那样,与数据包 963()的连接根本没有冻结 - 设备实际上在下一个数据包中做出应答,并且它会一直持续工作直到捕获结束。与数据包 969 ( ) 的连接
tcp.stream eq 5
是一个非常短暂的连接,它建立于数据包 879 中,并且它做冻结,但不是由于使用 SACK;此时只有一个段需要确认,而设备只是没有对其进行确认。“SACK_PERM”数据包(所有数据包
tcp.stream eq 6
)是重置后建立新连接的一次尝试(客户端会尝试重新传输 SYN,但会被忽略);但是,其中的 SACK_PERM 选项与在职的TCP 连接,因此不太可能是导致连接尝试被忽略的原因。