如何在没有等待响应的情况下通过单个TCP连接发送多个请求?C#
c#
目前,我正在尝试以更快的方式通过单个连接发送许多原始请求。我使用 HTTPClient lib 实现了这一点,但由于需要发送原始字节,我使用的是 TCPClient。
此应用程序的一些必要条件:
- 1 个连接
- 在管道中提交所有请求,继续发送,无需等待每次读取
- 发送原始请求
我有什么代码:
发送所有请求的方法
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);
目前行为:
回答
如果你想发送多个请求,你实际上只是:发送多个请求。目前尚不清楚这里的问题是什么,或者您看到了什么意外行为。然而!几点考虑:
- 虽然您不需要等待每个响应,但您确实需要等待每次写入- 您不能从两个不同的上下文同时写入同一个套接字(您目前正在这样做)
- TCP 是一个流;没有固有的框架——所有保证的是相同的字节将以正确的顺序到达(或最终失败);所以:当发送多条消息时,你需要添加帧(这样你就知道每条消息的开始和结束位置);例如,这可能是基于文本协议中的 CR/LF 终止符,或二进制协议中的长度前缀
- 你需要一个:用这种管道打交道时,你不能读作写的部分(因为这将违抗点),所以单独的读循环,只是如果需要读取的答复,并将其相关因素回请求; 这可能意味着一个队列,如果回复总是按照请求排序,或者一个字典,如果回复可能乱序,由某个相关标识符键控
- 老实说,这种网络代码是不平凡的