如何在不等待响应的情况下通过单个 TCP 连接发送多个请求? C#
How send many requests over a single TCP connection without wait responses? C#
目前,我正在尝试以更快的方式通过单个连接发送许多原始请求。我使用 HTTPClient 库实现了这一点,但由于需要发送原始字节,我使用的是 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);
当前行为:
如果你想发送多个请求,你实际上只是:发送多个请求。目前尚不清楚这里的问题是什么,或者您看到的是什么意外行为。然而!一些注意事项:
- 虽然您不需要等待每个 响应,但您确实需要等待每个 write - 您不能同时写入从两个不同的上下文到同一个套接字(你目前正在做)
- TCP 是一个流;没有固有的框架——所有可以保证的是相同的字节将以正确的顺序到达(或最终失败);所以:当发送多条消息时,you 需要添加框架(这样你就知道每条消息的开始和结束位置);例如,这可能是基于文本的协议中的 CR/LF 终止符,或者是二进制协议中的长度前缀
- 在处理这种管道时,您不能将读取作为写入的一部分(因为那样会违背这一点),因此:您需要一个 separate读取循环,只是读取回复,并在需要时将它们关联回请求;这可能意味着一个队列,如果回复总是关于请求排序,或者一个字典,如果回复可能是无序的,由一些相关标识符
键入
- 老实说,这种网络代码并不平凡
目前,我正在尝试以更快的方式通过单个连接发送许多原始请求。我使用 HTTPClient 库实现了这一点,但由于需要发送原始字节,我使用的是 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);
当前行为:
如果你想发送多个请求,你实际上只是:发送多个请求。目前尚不清楚这里的问题是什么,或者您看到的是什么意外行为。然而!一些注意事项:
- 虽然您不需要等待每个 响应,但您确实需要等待每个 write - 您不能同时写入从两个不同的上下文到同一个套接字(你目前正在做)
- TCP 是一个流;没有固有的框架——所有可以保证的是相同的字节将以正确的顺序到达(或最终失败);所以:当发送多条消息时,you 需要添加框架(这样你就知道每条消息的开始和结束位置);例如,这可能是基于文本的协议中的 CR/LF 终止符,或者是二进制协议中的长度前缀
- 在处理这种管道时,您不能将读取作为写入的一部分(因为那样会违背这一点),因此:您需要一个 separate读取循环,只是读取回复,并在需要时将它们关联回请求;这可能意味着一个队列,如果回复总是关于请求排序,或者一个字典,如果回复可能是无序的,由一些相关标识符 键入
- 老实说,这种网络代码并不平凡