ソケット通信は、ネットワーク上でデータを交換するための基本的な手段です。
この記事では、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();
}
}
}
コードの概要
- ネットワーク情報の取得
- ソケットの設定とクライアントの受け入れ
- データの受信と送信
- ソケットのクローズ
ネットワーク情報の取得
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.Stream
とProtocolType.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());
}
}
}
コードの概要
- ネットワーク情報の取得
- ソケットの設定とサーバーへの接続
- データの送信と受信
- ソケットのクローズ
ネットワーク情報の取得
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#を使用したソケット通信の基本について解説しました。
ソケットはネットワークプログラミングにおいて非常に重要なコンポーネントであり、正しく理解して使用することで、多様なネットワークベースのアプリケーションを開発することが可能です。
プログラミングスキルをさらに高めたい方は、これを基にさまざまな応用を探求してみてください。