はじめに
UDP通信をC#で実装する方法は2つあります。1つは低レベルのSocketクラスを直接使う方法、もう1つはより高レベルなUdpClientクラスを利用する方法です。後者のほうがコード量が少なく簡単です。
以下、それぞれの実装例を示します。
方法1:Socketクラスをラップした簡易ライブラリ
送信側(クライアント)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace UdpSimple
{
// UDP送信をラップするクラス
public class UdpSender : IDisposable
{
private Socket socket;
public UdpSender()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
public void Send(string message, string ip, int port)
{
if (string.IsNullOrEmpty(message))
{
Console.WriteLine("メッセージが空です");
return;
}
byte[] bytes = Encoding.UTF8.GetBytes(message);
EndPoint remote = new IPEndPoint(IPAddress.Parse(ip), port);
socket.SendTo(bytes, remote);
}
public void Dispose()
{
socket?.Close();
}
}
class Program
{
static void Main()
{
Console.WriteLine("送信するメッセージを入力してください");
using (var sender = new UdpSender())
{
while (true)
{
string msg = Console.ReadLine();
if (msg == "exit") break;
sender.Send(msg, "192.168.1.104", 3333);
Console.WriteLine("送信しました");
}
}
}
}
}
受信側(サーバー)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace UdpSimple
{
public class UdpReceiver : IDisposable
{
private Socket socket;
private CancellationTokenSource cts;
public UdpReceiver(string localIp, int localPort)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Parse(localIp), localPort));
}
public void StartListening()
{
cts = new CancellationTokenSource();
Task.Run(() => ReceiveLoop(cts.Token));
}
private void ReceiveLoop(CancellationToken token)
{
byte[] buffer = new byte[1024];
EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
while (!token.IsCancellationRequested)
{
try
{
int len = socket.ReceiveFrom(buffer, ref remote);
string msg = Encoding.UTF8.GetString(buffer, 0, len);
var clientEP = (IPEndPoint)remote;
Console.WriteLine($"受信元: {clientEP.Address}:{clientEP.Port} → 内容: {msg}");
}
catch (SocketException ex)
{
Console.WriteLine($"受信エラー: {ex.Message}");
}
}
}
public void Stop()
{
cts?.Cancel();
}
public void Dispose()
{
Stop();
socket?.Close();
cts?.Dispose();
}
}
class Program
{
static void Main()
{
using (var receiver = new UdpReceiver("192.168.1.104", 3333))
{
receiver.StartListening();
Console.WriteLine("受信を開始しました。Enterキーで終了");
Console.ReadLine();
}
}
}
}
方法2:UdpClientクラスを使った簡易実装
受信側(サーバー)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace UdpClientSample
{
class Program
{
static void Main()
{
using (var client = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.1.104"), 3333)))
{
IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine("受信待機中…");
while (true)
{
byte[] data = client.Receive(ref remote);
string msg = Encoding.UTF8.GetString(data);
Console.WriteLine($"送信元: {remote.Address}:{remote.Port} → メッセージ: {msg}");
}
}
}
}
}
送信側(クライアント)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace UdpClientSample
{
class Program
{
static void Main()
{
using (var client = new UdpClient())
{
Console.WriteLine("送信するメッセージを入力してください");
while (true)
{
string msg = Console.ReadLine();
if (msg == "exit") break;
byte[] data = Encoding.UTF8.GetBytes(msg);
client.Send(data, data.Length, new IPEndPoint(IPAddress.Parse("192.168.1.104"), 3333));
}
}
}
}
}
補足
上記のコードでは、ローカルIPアドレスを192.168.1.104と仮定しています。実際の環境に合わせて変更してください。また、UdpClientを使用する場合は、明示的なクローズ処理をusing文で自動化しています。