TCPClient 的性能非常慢

Terribly slow performance of TCPClient

出于学习目的(我想牢牢掌握 HTTP 内部结构)我正在编写简单的 HTTP 服务器,它将根据 rfc7230-7235 解析请求并将其代理到我的简单后端服务器。

我不希望击败任何现有解决方案,但显然 TCPClient 由于某种原因工作速度非常慢。直接调用我的后端在更糟糕的情况下只需要 20 毫秒,而使用我的简单服务器调用它至少需要 200 毫秒,这太糟糕了。

撇开解析不谈,这对响应时间的影响几乎微不足道,这是最小的代码,可以接收响应并将其原样发送到后端:

public static async Task Main()
{
    Logger.Info("Start listener.");
    var listener = new TcpListener(IPEndPoint.Parse("0.0.0.0:5000"));
    listener.Start();

    while (true)
    {
        var client = await listener.AcceptTcpClientAsync();

        using var c_stream = client.GetStream();

        // read request
        using var ms = new MemoryStream();
        int i;
        var buffer = new byte[1024];
        while ((i = await c_stream.ReadAsync(buffer, 0, 1024)) != 0)
        {
            await ms.WriteAsync(buffer, 0, i);
            if (i < 1024) break;
        }

        // write whole request as-is to backend
        using var backend = new TcpClient();
        await backend.ConnectAsync(IPEndPoint.Parse("172.21.215.119:3000"));
        var b_stream = backend.GetStream();

        ms.Position = 0;
        ms.WriteTo(b_stream);
        await b_stream.FlushAsync();

        // read output from backend to memory
        ms.Position = 0;
        while ((i = await b_stream.ReadAsync(buffer, 0, 1024)) != 0)
        {
            await ms.WriteAsync(buffer, 0, i);
            if (i < 1024) break;
        }

        // send back to fuckin client
        ms.Position = 0;
        ms.WriteTo(c_stream);
        await c_stream.FlushAsync();
    }
}

我不知道这是否重要,但我的环境看起来像这样:

  1. 我正在 windows 10 台装有 WSL 2 的机器上工作。
  2. 后端在 WSL 上设置 (ubuntu)。这只是nestjs上的宠物店。
  3. 后端调用 mongodb,这是在 docker 环境(也是 WSL)中设置的。

在我的最小代码示例中,每个请求需要 200-250 毫秒,至少在我的机器上是这样。它与我的实际代码的工作方式没有太大区别。最大的区别可能是,我正在为每个请求发送垃圾邮件任务,并且我有很多与 RFC 要求相关的验证。

如果有一些关于如何正确使用 TCPClient(或必要时使用 Sockets)的好资源,我会很乐意接受。

好吧,看来答案很……打扰了……

我通过将对 http://localhost:port 的调用更改为 http://127.0.0.1:port 来解决这个问题。

现在即使是我在这个例子中的愚蠢代理实现,最少的代码也需要几毫秒才能完成 运行。

windows 上的本地主机解析似乎存在某种问题,老实说这超出了我的范围。显然这不仅是我的问题,reddit 上的一些用户 (post) 帮助了我,在尝试 运行 类似于我的代码时遇到了同样的问题。