[C#] 非同期ソケット通信で簡易TCPクライアントを作成する

[C#] 非同期ソケット通信で簡易TCPクライアントを作成する

非同期ソケット通信

C#で複数のクライアントを同時に接続可能な、簡易echoサーバーに接続するためのクライアントを作成してみます。通信には非同期なソケット通信を使用します。次のURLを参考にしています。

サーバーは以下の記事で作成しています。

[C#] 非同期ソケット通信で簡易チャットサーバーを作成する

クライアント

メッセージの送信と非同期の受信待機を行います。受信したデータを文字列として表示するだけです。

サーバーはクライアントからの要求を待機し、メッセージを送信したらまるっとその文字列を返して来るように作ったので、送信したメッセージが送り返され、画面に表示されます。

クライアントの仕組みはサーバーに比べて単純です。受信のみ非同期で行います。接続、切断、送信は同期で行ってますが、同じように非同期でも行えます。

受信の非同期待機は、サーバーのときと同じです。同じ理由でサーバーから強制的に切断されると例外が出てしまいますが。

public class Client
{
    public IPEndPoint ServerIPEndPoint { get; set; }
    private Socket Socket { get; set; }
    public const int BufferSize = 1024;
    public byte[] Buffer { get; } = new byte[BufferSize];

    public Client()
    {
        this.ServerIPEndPoint = new IPEndPoint(IPAddress.Loopback, 12345);
    }

    // ソケット通信の接続
    public void Connect()
    {
        this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        this.Socket.Connect(this.ServerIPEndPoint);

        // 非同期で受信を待機
        this.Socket.BeginReceive(this.Buffer, 0, BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), this.Socket);
    }

    // ソケット通信接続の切断
    public void DisConnect()
    {
        this.Socket?.Disconnect(false);
        this.Socket?.Dispose();
    }

    // メッセージの送信(同期処理)
    public void Send(string message)
    {
        var sendBytes = new UTF8Encoding().GetBytes(message);
        this.Socket.Send(sendBytes);
    }

    // 非同期受信のコールバックメソッド(別スレッドで実行される)
    private void ReceiveCallback(IAsyncResult asyncResult)
    {
        var socket = asyncResult.AsyncState as Socket;

        var byteSize = -1;
        try
        {
            // 受信を待機
            byteSize = socket.EndReceive(asyncResult);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return;
        }

        // 受信したデータがある場合、その内容を表示する
        // 再度非同期での受信を開始する
        if (byteSize > 0)
        {
            Console.WriteLine($"{Encoding.UTF8.GetString(this.Buffer, 0, byteSize)}");
            socket.BeginReceive(this.Buffer, 0, this.Buffer.Length, SocketFlags.None, ReceiveCallback, socket);
        }
    }
}

非同期のコールバック処理は別スレッドで実行されます。GUIを操作したりするのは考慮しなければなりません。

C#カテゴリの最新記事