我已经开始构建一个 tcp 服务器,它将能够接受许多客户端,并同时从所有客户端接收新数据。
到目前为止,我将 IOCP 用于 tcp 服务器,这非常简单和舒适,但这次我想使用 Async / Await 技术。在 C# 5.0 中发布。
问题是,当我开始使用 async/await 编写服务器时,我发现在 tcp 多用户服务器用例中,async/await 技术。并且常规的同步方法也一样。
这是一个更具体的简单示例:
class Server
{
private TcpListener _tcpListener;
private List<TcpClient> _clients;
private bool IsStarted;
public Server(int port)
{
_tcpListener = new TcpListener(new IPEndPoint(IPAddress.Any, port));
_clients = new List<TcpClient>();
IsStarted = false;
}
public void Start()
{
IsStarted = true;
_tcpListener.Start();
Task.Run(() => StartAcceptClientsAsync());
}
public void Stop()
{
IsStarted = false;
_tcpListener.Stop();
}
private async Task StartAcceptClientsAsync()
{
while (IsStarted)
{
// ******** Note 1 ********
var acceptedClient = await _tcpListener.AcceptTcpClientAsync();
_clients.Add(acceptedClient);
IPEndPoint ipEndPoint = (IPEndPoint) acceptedClient.Client.RemoteEndPoint;
Console.WriteLine("Accepted new client! IP: {0} Port: {1}", ipEndPoint.Address, ipEndPoint.Port);
Task.Run(() => StartReadingDataFromClient(acceptedClient));
}
}
private async void StartReadingDataFromClient(TcpClient acceptedClient)
{
try
{
IPEndPoint ipEndPoint = (IPEndPoint) acceptedClient.Client.RemoteEndPoint;
while (true)
{
MemoryStream bufferStream = new MemoryStream();
// ******** Note 2 ********
byte[] buffer = new byte[1024];
int packetSize = await acceptedClient.GetStream().ReadAsync(buffer, 0, buffer.Length);
if (packetSize == 0)
{
break;
}
Console.WriteLine("Accepted new message from: IP: {0} Port: {1}\nMessage: {2}",
ipEndPoint.Address, ipEndPoint.Port, Encoding.Default.GetString(buffer));
}
}
catch (Exception)
{
}
finally
{
acceptedClient.Close();
_clients.Remove(acceptedClient);
}
}
}
现在,如果您看到“注 1”和“注 2”下的行,它可以很容易地更改为:
注1来自
var acceptedClient = await _tcpListener.AcceptTcpClientAsync();
至
var acceptedClient = _tcpListener.AcceptTcpClient();
和注2
int packetSize = await acceptedClient.GetStream().ReadAsync(buffer, 0, 1024);
至
int packetSize = acceptedClient.GetStream().Read(buffer, 0, 1024);
服务器将完全一样地工作。
那么,如果与使用常规同步方法一样,为什么要在多个用户的 tcp 侦听器中使用 async / await 呢?
在这种情况下我应该继续使用 IOCP 吗?因为对我来说它非常简单和舒适,但我担心它会被淘汰,甚至在较新的 .NET 版本中不再可用。