如何在不等待响应的情况下通过单个 TCP 连接发送多个请求? C#

How send many requests over a single TCP connection without wait responses? C#

目前,我正在尝试以更快的方式通过单个连接发送许多原始请求。我使用 HTTPClient 库实现了这一点,但由于需要发送原始字节,我使用的是 TCPClient。

此应用程序的一些必要条件:

我有什么代码:

发送所有请求的方法

private static async Task SendAllRequests(Dictionary<int, string> requestsDictionary)
        {
            var client = new TcpClient();
            var ipAddress = Dns.GetHostEntry("localhost").AddressList[0];

            await client.ConnectAsync("localhost", 44392);
            SslStream sslStream = new SslStream(
                client.GetStream(),
                false,
                null
            );
            await sslStream.AuthenticateAsClientAsync("localhost");

            var tasks = new List<Task<KeyValuePair<int, SslStream>>>();

            foreach (var k in requestsDictionary.Keys)
            {

                tasks.Add(SendStreamAsync(requestString, sslStream));
            }

            var requestsInfo = await Task.WhenAll(tasks);
       }

发送和读取单个请求字节的方法

            byte[] buffer = new byte[2048];
            int bytes;
 
            byte[] request = Encoding.UTF8.GetBytes(requestString);
            await sslStream.WriteAsync(request, 0, request.Length);
            await sslStream.FlushAsync();

            do
            {
                bytes = await sslStream.ReadAsync(buffer, 0, buffer.Length);
            } while (bytes == 2048);


当前行为:

如果你想发送多个请求,你实际上只是:发送多个请求。目前尚不清楚这里的问题是什么,或者您看到的是什么意外行为。然而!一些注意事项:

  • 虽然您不需要等待每个 响应,但您确实需要等待每个 write - 您不能同时写入从两个不同的上下文到同一个套接字(你目前正在做)
  • TCP 是一个;没有固有的框架——所有可以保证的是相同的字节将以正确的顺序到达(或最终失败);所以:当发送多条消息时,you 需要添加框架(这样你就知道每条消息的开始和结束位置);例如,这可能是基于文本的协议中的 CR/LF 终止符,或者是二进制协议中的长度前缀
  • 在处理这种管道时,您不能将读取作为写入的一部分(因为那样会违背这一点),因此:您需要一个 separate读取循环,只是读取回复,并在需要时将它们关联回请求;这可能意味着一个队列,如果回复总是关于请求排序,或者一个字典,如果回复可能是无序的,由一些相关标识符
  • 键入
  • 老实说,这种网络代码并不平凡