Linux TCP,如何调试写入流的意外延迟?

Linux TCP,如何调试写入流的意外延迟?

问题:我的音乐服务器代码在阻塞套接字上使用简单的 TCP 连接,需要将字节流式传输到客户端(恰好是 Logitech 挤压盒)。这并不复杂 - 从文件中读取 64k,将其写入挤压盒,然后重复。它全部运行在一个并不繁忙的本地 LAN 上,服务器和挤压盒客户端插入同一台交换机。挤压盒不会很快消耗流,因此服务器在几乎任何硬件上都应该可以毫无问题地满足客户端的需求。

而当服务器运行在Raspberry pi 3B+上时,实际上完全没有问题。圆周率为零可能可以跟上。当它在我的 Linux 笔记本电脑上运行时,同上,一切都很好。我可以定期询问挤压盒的内部缓冲区有多满,它很快就会达到大约 99+%,并保持在那里。正如您所期望的,服务器 write()(在前几个之后)大部分时间都处于阻塞状态。

但我将服务器移至运行 Linux 的 Azulle Inspire,并插入同一交换机,然后出现了严重错误。音乐开始播放,但很快就断断续续地消失了。挤压盒报告缓冲区开始填满,但随后有些东西停止运行,缓冲区很快清空(有时会稍微上升,所以我认为一些流量通过,但还不够接近),从而停止了音乐。服务器声称它正在继续写入,但写入时间比我预期的要长。

请注意,Azulle 还有其他偶尔的网络任务,并且它们都工作正常,尽管我可能不会注意到大多数其他应用程序的短暂网络延迟。但是当音乐服务器运行时,NUC(和网络)处于空闲状态 - 这不是 CPU 或带宽问题。

我尝试过更换电缆、更换交换机以及使用交换机上的不同端口。我尝试过发送不同的缓冲区大小。没有效果。我能想到的就是 TCP 堆栈或以太网硬件有一些非常奇怪的地方。

我该如何调试这个? Linux 笔记本电脑运行良好,运行的是 Linux 4.15.0-55-generic(并且 apt 升级不会改变这一点)。 Azuelle 运行的是 Linux 4.15.0-64-generic、Mint。我不敢相信 4.15.0 中 TCP 处理发生了根本性的变化。我对 tcpdump 等工具不太熟悉,更不用说内核配置或调试了,所以我正在寻找一些帮助......

Linux 笔记本电脑和 Azuelle 之间的 ping 时间始终在 0.2 毫秒和 0.35 毫秒左右,典型值为 0.33 毫秒。

我迷路了。 TIA。

答案1

使用 tcpdump 捕获您的流:

tcpdump -i iface -s 1500 -w out.cap 'tcp and port xxx'

其中iface是网络接口,xxx是两个端口号之一。

然后out.cap用wireshark打开,看看你能从跟踪中得到什么。那里发生的事情应该是显而易见的。如果没有,请重新发帖。

FWIW,从你所说的来看,这听起来像是 MTU 问题。

答案2

嗯,这就是我需要的线索。

当我对 MTU 大小感到好奇时发现了这一点:

/sys/class/net/enp1s0/mtu:1500 /sys/class/net/lo/mtu:65536 /sys/class/net/wlp2s0/mtu:1500

一切都很好,但 wlp 看起来像是无线连接。无线的?那还开着吗?因此,我在 wlp... 接口上执行了 tcpdump,然后看到了一条从协议中识别出的消息,然后是一长串 ACK,除此之外什么也没有,流媒体播放了几秒钟的音乐,然后失败了。

然后我关闭无线并再次尝试。没有口吃。一切顺利。

奇怪的是,服务器距离无线接入点只有几英尺。即使它正在使用它,也不应该出现带宽不足的情况。我想知道是否出于某种原因同时打开两者会导致问题,但我认为这是不可能的......

相关内容