多くのクライアントを受け入れ、すべてのクライアントから同時に新しいデータを受信できるtcpサーバーの構築を開始しました。
今までtcpサーバーにIOCPを使っていてかなり楽で快適だったのですが、今回はAsync/Awaitの技術を使いたいと思います。C# 5.0 でリリースされました。
問題は、async / await を使用してサーバーの作成を開始したときに、tcp 複数ユーザー サーバーのユース ケース async / await tech であることがわかりました。通常の同期方法は同じように機能します。
より具体的にするための簡単な例を次に示します。
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);
}
}
}
'Note 1' と 'Note 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 バージョンでは利用できなくなるのではないかと心配しています。