减慢 TCP/IP 接收速度

Slow down in TCP/IP receive speed

我编写了一个简单的 .Net 客户端,它通过 TCP/IP 连接到硬件设备 (FPGA)。当我单击客户端中的一个按钮时,它会向设备发送一个小的(4 字节)"request",然后立即读取设备响应的数据块(大约 32kb)。客户端代码看起来像这样:-

var stream = _tcpClient.GetStream();

stream.Write(requestData, 0, requestData.Length);

using (var ms = new MemoryStream())
{
    var tempBuffer = new byte[65535];
    do
    {
        var numBytesRead = stream.Read(tempBuffer, 0, tempBuffer.Length);
        ms.Write(tempRead, 0, numBytesRead);
    }
    while(ms.Length < ExpectedResponseSize);

    _hardwareResponse = ms.ToArray();
}

在上面的代码中使用 Stopwatch 通常会报告 2-3ms 来读取整个 32kb 的响应,如果我反复缓慢地单击按钮(例如每秒一次),这个时间将保持一致。

如果我开始更快速地点击按钮(例如每半秒一次),那么几秒钟后时间会突然下降到 12 毫秒左右并保持在那里,即使我返回缓慢点击按钮也是如此。如果我关闭然后重新打开客户端上的连接并重试,它会回到 2-3 毫秒时间。

WireShark 显示在更快的响应期间从 PC 发出 3-4 个 ACK​​,但一旦时间下降到 12 毫秒,这会增加到十几个或更多。在这两种情况下,来自 FPGA 的数据包的数量和大小都是相同的。我非常有信心,这不是客户端或 FPGA 上的代码的问题(两者都不会变得更简单)——直觉是它是协议或网络的问题。有什么想法吗?

您是否看过这个类似问题的各种答案:https://serverfault.com/questions/215674/latency-in-tcp-ip-over-ethernet-networks/215963?我怀疑问题是 window 大小或 ack 算法悲观地重新配置自身,但唯一真正的方法是在客户端和服务器上一次调整一件事,直到你发现性能差异。默认情况下使用许多自适应算法(如 Nagle),有时会对本地流量产生意想不到的后果。