通过网络发送大量数据时,我发现一些间歇性网络问题,有人建议我将此选项设置为 1 可能会解决该问题。
根据文档:
tcp_workaround_signed_windows (Boolean; default: disabled; since Linux
2.6.26)
If enabled, assume that no receipt of a window-scaling option
means that the remote TCP is broken and treats the window as a
signed quantity. If disabled, assume that the remote TCP is not
broken even if we do not receive a window scaling option from
it.
了解 TCP 的任何人都可以澄清这个参数到底是做什么的吗?我不确定什么是窗口缩放,也不确定“假设没有收到窗口缩放选项意味着远程 TCP 已损坏”如何在这种情况下提供显着帮助。
我还应该提到,我还没有准确地缩小我遇到的问题是什么,只是间歇性地出现这个问题,并且数据传输会意外挂起(Wireshark 显示两台机器之间的数据包传输停止)并且它有其他几个人引起我的注意,据说设置这个值似乎有帮助。
谢谢
答案1
在 TCP 中,窗口大小是一个 16 位无符号字段,指示接收器当前还有多少字节的数据可以接收。
事实证明,16 位还不够,因为在任何给定时间只允许传输 64KB 的数据。这就是引入窗口缩放选项的原因。通过窗口缩放,该字段仍然只有 16 位,但它不必计算单个字节,而是可以一次计算 2、4、8、...或 16384 个字节。
窗口缩放工作原理的确切细节与您的问题并不特别相关。因为您引用的解释表明该tcp_workaround_signed_windows
选项仅在不使用窗口缩放时适用。
该选项仅在禁用窗口缩放时适用的原因可能是,它是针对仅在不支持窗口缩放的旧系统上出现的错误的解决方法。
错误
该引用提到了一个有缺陷的接收器将窗口大小字段视为有符号值。这意味着对于最大 32KB 的所有值,它都可以正常工作,但任何 32KB 或更大的值都将被错误地解释为负数。
这样做的效果是,如果您告诉具有此错误的对等方您当前有内存可以接收 48KB 以上的数据,则对等方会将其误解为 -16KB 并停止发送更多数据,因为它想要发送的下一个 1.4KB 显然已获胜不适合。 (或者当它在一个本来应该是正值的字段中看到负值时,它可能会做一些比这更愚蠢的事情。)
如果您遇到此错误,您会看到,当与运行某些非常旧的软件的特定计算机进行通信时,数据传输将无缘无故地停止。
这可以通过从不发送大于 32KB 的窗口大小来解决,我希望设置从该描述中做到这一点。
设置有什么作用?
将可用窗口大小从 64KB 减少到 32KB 将避免与遭受此错误的 TCP 实现通信时出现连接停顿。
但这是有代价的。如果传输速度受到窗口大小的限制,那么将窗口大小减小一半也会使传输速度降低一半。因此,原本运行速度比应有速度慢的传输最终可能只会以一半的速度运行。
这就是为什么这种解决方法没有永久启用的原因。
为什么只在不使用窗口缩放时解决该问题?
该错误与窗口缩放之间没有直接联系。所以我猜测考虑窗口缩放的唯一原因是因为它是检测特定错误实现的最著名的启发式方法。
听起来确实很可能在任何人开始实现窗口缩放之前,这样的错误就会得到修复。毕竟,如果您需要更大的窗口,那么不修复将窗口大小限制为实际大小一半的错误将是愚蠢的。
答案2
窗口缩放是一个可以在 TCP 中设置的选项,它允许接收缓冲区的扩展大小(大于最初允许的大小)。我不清楚这个选项有什么帮助。我想也许如果实现中存在错误,那么设置这种方式或另一种方式可能会避免该错误,但实际上,TCP 应该以任何一种方式工作(在一种情况下,它可能只是比需要的更频繁地进行确认)。