6

多くのクライアントを受け入れ、すべてのクライアントから同時に新しいデータを受信できる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 バージョンでは利用できなくなるのではないかと心配しています。

4

3 に答える 3

1

いくつか検索した後、これを見つけまし

Q : これは TCPServer のプラクティスのリストですが、毎秒 5000 以上のクライアントを管理するためのベスト プラクティスはどれですか?

A:私の仮定は、「非同期メソッドを書く」ことです。データベースを同時に操作している場合は、「非同期メソッドとイテレータ」の方が多くなります

于 2016-01-15T06:31:22.273 に答える
0

async/await を使用したサンプル コードを次に示します。

非同期待機TCPサーバー

iocp よりも async/await を使用して tcp サーバーを構築する方が簡単だと思います。

于 2017-11-22T06:23:32.310 に答える