C# Visual Studio

【Visual Studio 2022】C#ソケット通信アプリケーションの作成

本記事では、C#を使ってサーバーとクライアント間でメッセージをやり取りするソケット通信アプリケーションの作成方法を解説します。サーバー・クライアントの役割や通信の仕組みを理解しながら、実際に動作するアプリを作る手順をステップごとに学べます。


ソケット通信とは

ソケット通信とは、コンピュータ同士がネットワーク上でデータをやり取りするための仕組みです。
普段私たちが使うWeb通信やメール送受信、工場でつかわれるPLCとの通信など、多くのネットワーク通信の土台になっています。

ソケットの役割

ソケット(Socket)は、データの出入り口のようなものです。
プログラムはソケットを通してデータを送ったり受け取ったりします。

クライアントとサーバー

ネットワーク通信は多くの場合、以下の2つの役割で行われます。

サーバー待ち受け役。データを受け取り、必要に応じて応答する。
クライアント送信役。サーバーにデータを送り、応答を受け取る。
TCPとUDP

ソケット通信には大きく2種類あります。

TCPデータが必ず届くことを保証。信頼性重視。
UDPデータが早く届くことを重視。届かないこともある。

完成イメージ

今回作成するアプリケーションは、サーバー側とクライアント側の2つのアプリケーションで構成されます。

動作の流れは以下の通りです。
1. サーバー接続待ち
2. クライアントがサーバーに接続
3. クライアントからサーバーへ「Hello Server !」とメッセージを送信
4. サーバーがメッセージを受信
5. サーバーからクライアントへ「Hello Client !」と応答
6. クライアントがメッセージを受信

「作成するアプリケーション」


機器構成

以下の機器構成を例にアプリケーションを作成します。


サーバーアプリケーションの作成

プロジェクト

・テンプレート:Windowsフォームアプリケーション(.NET Framework)
・言語:C#
・フレームワーク:.NET Framework 4.8

メイン画面
コントロール
名称コントロールの種類備考
固定文字1Label
固定文字2Label
受信メッセージLabel
実行ボタンButton
コード
C#
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace ArtApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btn_StartListen_Click(object sender, EventArgs e)
        {
            IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Any, 5000);

            //ソケットの作成
            TcpListener tcpListener = new TcpListener(listenEndPoint);

            try
            {
                // 待ち受け開始
                tcpListener.Start();

                //通信の確立
                //この処理はクライアントが接続するまでブロック(待機)
                using (TcpClient tcpClient = tcpListener.AcceptTcpClient())
                {
                    // NetworkStream を取得
                    using (NetworkStream networkStream = tcpClient.GetStream())
                    {
                        //データの受信
                        byte[] receiveBuffer = new byte[1024];
                        int receivedByteCount = networkStream.Read(receiveBuffer, 0, receiveBuffer.Length);

                        //受信データをバイト配列を文字列に変換
                        string receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, receivedByteCount);
                        this.lbl_ReceivedMessage.Text = receivedMessage;

                        //クライアントに応答メッセージを送信
                        string responseMessage = "Hello Client !";
                        byte[] responseBuffer = Encoding.UTF8.GetBytes(responseMessage);
                        networkStream.Write(responseBuffer, 0, responseBuffer.Length);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                tcpListener.Stop();
            }
        }
    }
}

クライアントアプリケーションの作成

プロジェクト

・テンプレート:Windowsフォームアプリケーション(.NET Framework)
・言語:C#
・フレームワーク:.NET Framework 4.8

メイン画面
コントロール
名称コントロールの種類備考
固定文字1Label
固定文字2Label
受信メッセージLabel
実行ボタンButton
コード
C#
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace ArtApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btn_ConnectAndSend_Click(object sender, EventArgs e)
        {
            //IPエンドポイントの作成
            IPAddress serverIpAddress = IPAddress.Parse("192.168.3.20");
            IPEndPoint serverEndPoint = new IPEndPoint(serverIpAddress, 5000);

            try
            {
                using (TcpClient tcpClient = new TcpClient())
                {
                    //サーバーへの接続
                    tcpClient.Connect(serverEndPoint);

                    using (NetworkStream networkStream = tcpClient.GetStream())
                    {
                        //サーバーへデータを送信
                        string sendMessage = "Hello Server !";
                        byte[] sendBuffer = Encoding.UTF8.GetBytes(sendMessage);
                        networkStream.Write(sendBuffer, 0, sendBuffer.Length);

                        //サーバーからの応答データを受け取る
                        byte[] receiveBuffer = new byte[1024];
                        int receivedByteCount = networkStream.Read(receiveBuffer, 0, receiveBuffer.Length);

                        //バイトデータを文字列に変換して表示
                        string receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, receivedByteCount);
                        this.lbl_ReceivedMessage.Text = receivedMessage;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

実行・動作確認

作成したアプリケーションを実行し、想定通りに動作するか確認してみましょう。

1. ノートPC1でサーバーアプリケーションを起動します。

2. ノートPC2でクライアントアプリケーションを起動します。

3. サーバーアプリケーションの実行ボタン(待ち受け開始)をクリックし、待ち受け状態にします。

4. クライアントアプリケーションの実行ボタン(接続して送信)をクリックし、「Hello Server !」を送信します。

5. サーバーからクライアントに「Hello Client !」が返ることを確認します。

完成イメージ通りに動作すれば、ソケット通信アプリケーションの作成は完了です。

今回作成したアプリケーションでは、通信処理をUIスレッド(メインスレッド)上で直接実行しているため、処理中に画面が固まったように見える場合があります。
ソケット通信では、接続待ちやデータ送受信などの待機時間が発生するため、これらを UI スレッドで処理するとアプリ全体の応答が一時的に停止してしまうためです。

実際のアプリケーション開発では、Task や Thread を用いて通信処理を別スレッドで実行する のが一般的です。
今回は、ソケット通信の基本的な流れを理解することを優先し、あえてシンプルな構成とするために UI スレッド上で動作させています。



あなたをプロにすることを約束します。

アルチテックのインターンシップはハイレベル。

現役のシステムエンジニアがマンツーマン指導

市場価値が高い産業系システムエンジニアを目指そう!

インターンシップの募集はこちら

-C#, Visual Studio
-, , , , ,