PR

【C#入門】ソケット通信(Socket)でネットワークプログラミングの基礎を学ぼう!

システム開発

ソケット通信は、ネットワーク上でデータを交換するための基本的な手段です。

この記事では、C#を使用してソケット通信の基本を学び、クライアントとサーバー間でのデータ交換の方法を解説します。

これを理解することで、ネットワークプログラミングの基礎を固めることができます。

ソケット通信とは?

ソケット通信は、異なるコンピュータ間や同一マシン上のプロセス間で通信を行うための技術です。TCP/IPプロトコルを用いた信頼性の高い通信が可能で、インターネットや企業内ネットワークで広く利用されています。

C#でのソケット通信の実装

C#でソケット通信を行うためには、System.Net.Sockets 名前空間を利用します。この名前空間は、ソケットの作成、データの送受信、ソケットの閉じ方など、ソケット操作に必要なクラスやメソッドを提供しています。

1. サーバーソケットの設定

サーバーはソケットを開いてクライアントの接続を待ち受ける役割を持ちます。以下はC#でサーバーソケットを設定する基本的なコードです。

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class Server
{
    public static void Main()
    {
        IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
        IPAddress ipAddr = ipHost.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);

        using (Socket listener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
        {
            listener.Bind(localEndPoint);
            listener.Listen(10);

            Console.WriteLine("Waiting for a connection...");
            Socket client = listener.Accept();

            // Data buffer
            byte[] bytes = new Byte[1024];
            string data = null;
            while (true)
            {
                int numByte = client.Receive(bytes);
                data += Encoding.ASCII.GetString(bytes, 0, numByte);
                if (data.IndexOf("<EOF>") > -1)
                    break;
            }

            Console.WriteLine("Text received -> {0} ", data);
            byte[] message = Encoding.ASCII.GetBytes("Test Server");
            client.Send(message);

            client.Shutdown(SocketShutdown.Both);
            client.Close();
        }
    }
}

コードの概要

  1. ネットワーク情報の取得
  2. ソケットの設定とクライアントの受け入れ
  3. データの受信と送信
  4. ソケットのクローズ

ネットワーク情報の取得

IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);
  • Dns.GetHostEntry()メソッドは、現在のホスト名を取得し、そのホストに関連付けられたIPアドレスとその他のネットワーク情報を含むIPHostEntryオブジェクトを返します。
  • Dns.GetHostName()は現在のマシンのホスト名を返します。
  • AddressList[0]は取得したIPアドレスのリストの最初のアドレスを指定します。
  • IPEndPointオブジェクトは、IPアドレスとポート番号(この例では11111)を組み合わせたエンドポイントを表します。

ソケットの設定とクライアントの受け入れ

using (Socket listener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
    listener.Bind(localEndPoint);
    listener.Listen(10);
    Console.WriteLine("Waiting for a connection...");
    Socket client = listener.Accept();
}
  • Socketクラスはネットワーク接続を介してデータの送受信を行うための主要な手段です。
  • このSocketはTCP接続用に設定されています(SocketType.StreamProtocolType.Tcp)。
  • Bindメソッドはソケットをローカルエンドポイントにバインドします。
  • Listenメソッドはソケットが接続を受け入れる準備ができていることをシステムに指示し、ここでは最大10の接続を待機できるように設定しています。
  • Acceptメソッドは接続要求を待ち、クライアントからの接続が確立されるとそのソケットを返します。

データの受信と送信

byte[] bytes = new Byte[1024];
string data = null;
while (true)
{
    int numByte = client.Receive(bytes);
    data += Encoding.ASCII.GetString(bytes, 0, numByte);
    if (data.IndexOf("<EOF>") > -1)
        break;
}
Console.WriteLine("Text received -> {0} ", data);
byte[] message = Encoding.ASCII.GetBytes("Test Server");
client.Send(message);
  • byte[] bytesは受信データを格納するためのバッファです。
  • Receiveメソッドはクライアントからデータを受信し、受信したバイト数を返します。
  • 受信したデータはASCII文字列に変換され、すべてのデータが受信されるまでこの操作を繰り返します。<EOF>文字列が受信データに含まれていると、ループから抜け出します。
  • 受信したデータをコンソールに表示後、応答として”Test Server”というメッセージをクライアントに送信します。

ソケットのクローズ

client.Shutdown(SocketShutdown.Both);
client.Close();
  • Shutdownメソッドはソケットの送受信活動を停止します(SocketShutdown.Bothは受信と送信の両方を指示します)。
  • Closeメソッドはソケットを閉じ、すべてのリソースを解放します。

2. クライアントソケットの設定

クライアントはサーバーに接続し、データを送受信します。以下はクライアントソケットを設定するための基本的なC#コードです。

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class Client
{
    public static void Main()
    {
        try
        {
            IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);

            using (Socket sender = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
            {
                sender.Connect(localEndPoint);

                // Sending message
                byte[] messageSent = Encoding.ASCII.GetBytes("Hello Server <EOF>");
                int byteSent = sender.Send(messageSent);

                // Receiving message
                byte[] messageReceived = new byte[1024];
                int byteRecv = sender.Receive(messageReceived);
                Console.WriteLine("Message from Server -> {0}", Encoding.ASCII.GetString(messageReceived, 0, byteRecv));

                sender.Shutdown(SocketShutdown.Both);
                sender.Close();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
}

コードの概要

  1. ネットワーク情報の取得
  2. ソケットの設定とサーバーへの接続
  3. データの送信と受信
  4. ソケットのクローズ

ネットワーク情報の取得

IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);
  • Dns.GetHostEntry()メソッドは、現在のホスト名を取得し、そのホストに関連付けられたIPアドレスとその他のネットワーク情報を含むIPHostEntryオブジェクトを返します。
  • Dns.GetHostName()は現在のマシンのホスト名を取得します。
  • AddressList[0]は、取得したIPアドレスリストの最初のアドレスです。
  • IPEndPointオブジェクトは、IPアドレスとポート番号(この例では11111)を組み合わせたエンドポイントを表します。これは、クライアントが接続を試みるサーバーのアドレスとポート番号です。

ソケットの設定とサーバーへの接続

using (Socket sender = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
    sender.Connect(localEndPoint);
}
  • Socketクラスを使用してTCPプロトコルで通信するソケットを作成します。
  • Connectメソッドは、指定されたIPEndPoint(サーバーのIPアドレスとポート)にソケットを接続します。

データの送信と受信

byte[] messageSent = Encoding.ASCII.GetBytes("Hello Server <EOF>");
int byteSent = sender.Send(messageSent);

byte[] messageReceived = new byte[1024];
int byteRecv = sender.Receive(messageReceived);
Console.WriteLine("Message from Server -> {0}", Encoding.ASCII.GetString(messageReceived, 0, byteRecv));
  • Encoding.ASCII.GetBytesメソッドを使用して、送信する文字列をバイト配列に変換します。この例では、”Hello Server “というメッセージをサーバーに送信します。
  • Sendメソッドは、接続されたソケットを通じてデータを送信します。
  • 受信用のバイト配列messageReceivedを定義し、Receiveメソッドでサーバーからの応答を待ち受けます。
  • 受け取ったデータはASCIIエンコーディングを使用して文字列に変換され、コンソールに表示されます。

ソケットのクローズ

sender.Shutdown(SocketShutdown.Both);
sender.Close();
  • Shutdownメソッドはソケットの送受信活動を停止します。SocketShutdown.Bothは送受信両方を停止させることを指示します。
  • Closeメソッドはソケットを閉じ、使用したリソースを解放します。

例外処理

catch (Exception e)
{
    Console.WriteLine(e.ToString());
}
  • このコードブロックは、接続の試み中に発生する可能性のある例外をキャッチし、その詳細をコンソールに出力します。これにより、開発中のデバッグが容易になります。

まとめ

この記事では、C#を使用したソケット通信の基本について解説しました。

ソケットはネットワークプログラミングにおいて非常に重要なコンポーネントであり、正しく理解して使用することで、多様なネットワークベースのアプリケーションを開発することが可能です。

プログラミングスキルをさらに高めたい方は、これを基にさまざまな応用を探求してみてください。

タイトルとURLをコピーしました