using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class UdpChatServer
{
private const int Port = 11000;
private readonly UdpClient _listener;
private readonly IPEndPoint _groupEp;
private volatile bool _running;
public UdpChatServer()
{
_listener = new UdpClient(Port);
_groupEp = new IPEndPoint(IPAddress.Any, Port);
}
public void Start()
{
_running = true;
Task.Run(ListenLoop);
Console.WriteLine($"伺服器啟動,監聽埠 {Port}...");
}
public void Stop()
{
_running = false;
_listener.Close();
}
private void ListenLoop()
{
try
{
while (_running)
{
byte[] bytes = _listener.Receive(ref _groupEp);
string msg = Encoding.GetEncoding("gb2312").GetString(bytes);
Console.WriteLine($"[{_groupEp.Address}] {msg}");
// 實務上可轉發給其他客戶端或存入資料庫
}
}
catch (SocketException) when (!_running) { /* 正常關閉 */ }
catch (Exception ex)
{
Console.Error.WriteLine($"監聽異常: {ex}");
}
}
}
public class UdpChatClient
{
private const int Port = 11000;
private readonly Socket _sender;
public UdpChatClient()
{
_sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_sender.EnableBroadcast = true; // 關鍵:允許發送廣播
}
public void Send(string message, string targetIp = "255.255.255.255")
{
var ep = new IPEndPoint(IPAddress.Parse(targetIp), Port);
byte[] data = Encoding.GetEncoding("gb2312").GetBytes(message);
_sender.SendTo(data, ep);
}
public void Dispose() => _sender.Dispose();
}
public partial class ChatForm : Form
{
private UdpChatClient _client;
private UdpChatServer _server;
private Thread _listenThread;
public ChatForm()
{
InitializeComponent();
_client = new UdpChatClient();
_server = new UdpChatServer();
}
private void ChatForm_Load(object sender, EventArgs e)
{
_listenThread = new Thread(() =>
{
var listener = new UdpClient(11000);
var ep = new IPEndPoint(IPAddress.Any, 11000);
while (true)
{
byte[] buf = listener.Receive(ref ep);
string msg = Encoding.GetEncoding("gb2312").GetString(buf);
Invoke(() => lstMessages.Items.Add($"[{ep.Address}] {msg}"));
}
}) { IsBackground = true };
_listenThread.Start();
}
private void btnSend_Click(object sender, EventArgs e)
{
_client.Send(txtInput.Text, "255.255.255.255"); // 廣播到全網段
txtInput.Clear();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
_client.Dispose();
base.OnFormClosing(e);
}
}
廣播(255.255.255.255)會被路由器阻擋,無法跨子網。生產環境建議改用 IP 組播(Multicast):
// 加入組播群組
var mcAddr = IPAddress.Parse("239.0.0.1");
_client.MulticastLoopback = true;
_client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
new MulticastOption(mcAddr));
// 發送至組播位址
_client.SendTo(data, new IPEndPoint(mcAddr, Port));
UDP 聊天室核心在於 UdpClient/Socket 綁定固定埠、設定 EnableBroadcast、使用 Receive/SendTo 收發。本文提供完整伺服器/客戶端/WinForms 三種整合方式,並指出生產環境應改用組播與可靠傳輸庫。掌握此基礎,即可擴充至即時遊戲同步、IoT 設備發現、日誌集中收集等場景。