C#でソケット通信を行う基本とサンプルコード

先生

C#でネットワークの扉を開こう!ソケット通信の基本からサンプルコードまで、わかりやすく解説します。

C# ソケット通信の基本

C# でのソケット通信は、ネットワークを介したアプリケーション間のデータ交換を可能にする強力な手段です。この記事では、ソケット通信の基本的な概念から、C# での実装方法、サンプルコードまでを解説します。初心者の方でも理解しやすいように、丁寧に説明していきます。

ソケット通信は、クライアントとサーバーという 2 つの役割を持つアプリケーション間で確立されます。サーバーは特定のポートで接続を待ち受け、クライアントはサーバーへの接続を要求します。接続が確立されると、双方向のデータ交換が可能になります。

C# では、System.Net.Sockets 名前空間のクラスを使用してソケット通信を実装します。主なクラスとしては、SocketTcpListener (サーバー側)、TcpClient (クライアント側) などがあります。

サーバー側の実装

サーバー側の実装では、まず TcpListener クラスを使用して、特定のポートで接続を待ち受けます。接続要求を受け付けると、Socket オブジェクトが作成され、クライアントとの通信に使用されます。

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

public class Server { 
 public static void Main(string[] args) { 
 TcpListener server = null; 
 try { 
 Int32 port = 13000; 
 IPAddress localAddr = IPAddress.Parse("127.0.0.1");

 server = new TcpListener(localAddr, port); 
 server.Start(); 

 Byte[] bytes = new Byte[256]; 
 String data = null; 

 while(true) { 
 Console.Write("Waiting for a connection... ");

 TcpClient client = server.AcceptTcpClient(); 
 Console.WriteLine("Connected!");

 data = null; 

 NetworkStream stream = client.GetStream(); 

 int i; 

 while ((i = stream.Read(bytes, 0, bytes.Length))!= 0) { 
 data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); 
 Console.WriteLine("Received: {0}", data); 

 byte[] msg = System.Text.Encoding.ASCII.GetBytes(data.ToUpper()); 

 stream.Write(msg, 0, msg.Length); 
 Console.WriteLine("Sent: {0}", data.ToUpper()); 
 } 

 client.Close(); 
 } 
 } 
 catch(SocketException e) { 
 Console.WriteLine("SocketException: {0}", e); 
 } 
 finally { 
 server.Stop(); 
 } 

 Console.WriteLine("\nHit enter to continue..."); 
 Console.Read(); 
 } 
}

上記の例では、127.0.0.1 の 13000 番ポートで接続を待ち受け、クライアントから受信したメッセージを大文字に変換して返信しています。

クライアント側の実装

クライアント側の実装では、TcpClient クラスを使用してサーバーに接続を要求します。接続が確立されると、NetworkStream を介してデータの送受信を行います。

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

public class Client { 
 public static void Main(string[] args) { 
 try { 
 Int32 port = 13000; 
 TcpClient client = new TcpClient("127.0.0.1", port); 

 Byte[] data = System.Text.Encoding.ASCII.GetBytes("Hello Server");

 NetworkStream stream = client.GetStream(); 

 stream.Write(data, 0, data.Length); 
 Console.WriteLine("Sent: {0}", "Hello Server");

 data = new Byte[256]; 

 String responseData = String.Empty; 

 Int32 bytes = stream.Read(data, 0, data.Length); 
 responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); 
 Console.WriteLine("Received: {0}", responseData); 

 stream.Close(); 
 client.Close(); 
 } 
 catch (ArgumentNullException e) { 
 Console.WriteLine("ArgumentNullException: {0}", e); 
 } 
 catch (SocketException e) { 
 Console.WriteLine("SocketException: {0}", e); 
 } 

 Console.WriteLine("\n Press Enter to continue..."); 
 Console.Read(); 
 } 
}

上記の例では、127.0.0.1 の 13000 番ポートで動作しているサーバーに接続し、「Hello Server」というメッセージを送信しています。サーバーからの応答を受信し、コンソールに表示します。

エラー処理

ソケット通信では、ネットワークの問題や相手側のアプリケーションの状態など、様々なエラーが発生する可能性があります。try-catch ブロックを使用して、これらのエラーを適切に処理することが重要です。SocketException クラスは、ソケット関連のエラーを表します。また、接続の確立、データ送受信のタイムアウト処理も重要です。

非同期通信

上記の例では同期的なソケット通信を行っていますが、大規模なアプリケーションや高負荷な状況では、非同期的な通信が推奨されます。BeginConnectEndConnectBeginReceiveEndReceive などのメソッドを使用することで、スレッドをブロックせずにソケット通信を行うことができます。Taskasync/awaitを使用すると、より簡単に非同期処理を記述できます。

参考リンク

まとめ

C# でのソケット通信は、ネットワークアプリケーション開発の基礎となる重要な技術です。この記事で紹介した基本的な概念とサンプルコードを参考に、様々なネットワークアプリケーションを開発してみてください。エラー処理や非同期通信についても理解を深めることで、より堅牢で効率的なアプリケーションを作成することができます。