我正在制作一个简单的服务器,它监听客户端并读取客户端请求,进行一些计算,然后向客户端发送响应并立即关闭连接(类似于HTTP)。
可能会有每秒钟出现很多连接,因此我希望让它尽可能快速和高效。
到目前为止,我能想到的最好方法如下所示:
注意:为了简化示例,我没有添加任何错误处理,例如try-catch,并且我知道这里的响应将始终为“Ok”。
这里的代码只是等待连接,当它到达
但是我应该使用stream.ReadAsync()还是stream.Read()?我很好奇是否重要,因为我已经在一个异步函数中,它不会阻塞主线程。
所以我的最终问题是:
1. 这是实现此任务的最佳/正确方法吗(也通过使用ManualResetEvent类)? 2. 在读写流时使用异步或非异步操作是否会有任何差异?(因为我没有阻塞主线程) 3. 如果它延迟,并且需要1-2秒才能发送/接收数据,是否仍然重要选择异步和非异步操作?
更新新改进的内容如下:
可能会有每秒钟出现很多连接,因此我希望让它尽可能快速和高效。
到目前为止,我能想到的最好方法如下所示:
private static ManualResetEvent gate = new ManualResetEvent(false);
static async void ListenToClient(TcpListener listener)
{
Console.WriteLine("Waiting for connection");
TcpClient client = await listener.AcceptTcpClientAsync();
Console.WriteLine("Connection accepted & establised");
gate.Set(); //Unblocks the mainthread
Stream stream = client.GetStream();
byte[] requestBuffer = new byte[1024];
int size = await stream.ReadAsync(requestBuffer, 0, requestBuffer.Length);
//PSEUDO CODE: Do some calculations
byte[] responseBuffer = Encoding.ASCII.GetBytes("Ok");
await stream.WriteAsync(responseBuffer, 0, responseBuffer.Length);
stream.Close();
client.Close();
}
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Any, 8888);
listener.Start();
while (true)
{
gate.Reset();
ListenToClient(listener);
gate.WaitOne(); //Blocks the main thread and waits until the gate.Set() is called
}
}
注意:为了简化示例,我没有添加任何错误处理,例如try-catch,并且我知道这里的响应将始终为“Ok”。
这里的代码只是等待连接,当它到达
await listener.AcceptTcpClientAsync()
时,它会跳回while循环并等待直到建立连接并调用gate.Set(),以便它可以再次监听新连接。因此,这将允许多个客户端同时连接(特别是如果计算需要很长时间)。但是我应该使用stream.ReadAsync()还是stream.Read()?我很好奇是否重要,因为我已经在一个异步函数中,它不会阻塞主线程。
所以我的最终问题是:
1. 这是实现此任务的最佳/正确方法吗(也通过使用ManualResetEvent类)? 2. 在读写流时使用异步或非异步操作是否会有任何差异?(因为我没有阻塞主线程) 3. 如果它延迟,并且需要1-2秒才能发送/接收数据,是否仍然重要选择异步和非异步操作?
更新新改进的内容如下:
private static ManualResetEvent gate = new ManualResetEvent(false);
static async Task ListenToClient(TcpListener listener)
{
//Same Code
}
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Any, 8888);
listener.Start();
while (true)
{
gate.Reset();
Task task = ListenToClient(listener);
task.ContinueWith((Task paramTask) =>
{
//Inspect the paramTask
});
gate.WaitOne(); //Blocks the main thread and waits until the gate.Set() is called
}
}