为什么通过 VPN 使用 VIM 时我的 TCP 窗口大小会变为零

为什么通过 VPN 使用 VIM 时我的 TCP 窗口大小会变为零

我使用 mac os 笔记本电脑通过典型的(即糟糕的)无线家庭网络,并通过 VPN 连接到工作。我通过 ssh 进入我办公室的 Linux(ubuntu)桌面。(当我说“我 ssh”时:我点击一个按钮,告诉我它将使用“ssh”,然后会打开一个“终端”窗口并登录到我的桌面。)

经常(一天最多几次)当我使用“vim”时,“vim”会停止响应,一两分钟后,与我的桌面的连接就会断开,终端会告诉我连接已断开。我经常一次在桌面上打开多个终端窗口,只有我正在使用“vim”的终端窗口会断开。其他窗口仍保持连接并可用。

最近我使用 tcpdump 跟踪来回传输的数据包,并捕获了一条跟踪信息,其中我的 vim 会话挂起并退出。在中断前几分钟,来自我桌面的数据包到达时窗口大小不断缩小,直到窗口大小为零,稍后连接断开。

我几乎可以理解这一点,因为我进入了插入模式,开始输入字符,而桌面却挂起了,而我在桌面乱七八糟的时候输入的内容填满了窗口。起始窗口大小约为 12,500,我输入的每个字符似乎都会生成一个 48 字节的数据包,因此大约 250 个字符可能会填满 tcp 缓冲区。

但是,当 vim 挂起时,更像是我向下翻页 (control-f),然后进入插入模式,然后开始输入几个字符。我的命令和字符被回显,表明 vim 正在接收和处理字符。

我不清楚 tpc 缓冲区位于套接字和“vim”之间的什么位置。大概 tty 驱动程序实际上是从 tcp 缓冲区中拾取字符,将它们回显给我,然后将它们交给 vim,再将 vim 的输出交还给我。但所有这些操作都会从 tcp 缓冲区中拉出字节,并且窗口大小不会变为零。

我对软件堆栈的工作原理有什么不理解的地方,为什么我的窗口大小会变为零,我该如何解决或修复该问题?

附加问题:

1) 为什么我的桌面将窗口大小设置为大约 12,500 而不是大约 64K?

2) 在 Mac 上使用 tcpdump 时,如果我使用“host hostname”、“host ipaddress”或“port 22”表达式(其中“hostname”和“ipaddress”替换为我的桌面的名称或 ip 地址),则不会得到任何输出。如果我不指定其中一个表达式,则会得到大量输出,并且输出显然包含我在命令行中指定的主机名、ipaddress 或端口。在 Mac 上,tcpdump 是否有什么特殊之处无法正常工作?是否存在搞砸命令行的标准方法,我对要求 tcpdump 执行的操作感到困惑?

谢谢,Cs

答案1

首先,TCP 窗口大小不是缓冲区,而是确认阈值。接收流量的节点每 x 个数据包仅发送一个 ACK​​ 数据包。在可靠的网络中,该数字应尽可能大以实现吞吐量 - 权衡是如果某些数据丢失,则必须重新传输整个窗口...这通常会导致 TCP 堆栈逐步减小窗口大小,以避免在未来发生数据包丢失时必须重新传输如此多的数据。有一个与可用内存(接收缓冲区)相关的组件,但在现代系统中,这几乎无关紧要。维基百科

此问题的根本原因可能是网络连接不良。VPN 经常会出现高延迟和/或数据包丢失,无线网络也是如此。作为实验,如果您通过有线连接而不是无线连接,问题是否会改善/解决?

相关内容