首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# UDP 協議實作多點廣播聊天室完整教學

     編輯:關於C#

UDP 特性與適用場景

  • 無連線、不可靠、無序、高效率、低延遲。
  • 適合:即時廣播、遊戲狀態同步、日誌收集、DNS、語音視訊(配合應用層重傳)。
  • 本範例實作「區域網廣播聊天」:單一埠號,所有客戶端收發同一多播組。

伺服器端:監聽廣播封包

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();
}

WinForms 整合範例(含接收顯示)

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));

編碼與安全注意事項

  • 編碼一致性:收發端必須使用相同編碼(範例用 gb2312,現代專案建議 UTF-8)。
  • 封包大小:UDP 單封包建議 ≤ 1472 位元組(MTU 1500 - IP/UDP 標頭),超大訊息需自行分片重組。
  • 無序/丟包:應用層需自行加序號、ACK、重傳機制(或改用 KCP、QUIC 等可靠 UDP 庫)。
  • 防火牆:需開放 UDP 埠號輸入/輸出規則。

總結

UDP 聊天室核心在於 UdpClient/Socket 綁定固定埠、設定 EnableBroadcast、使用 Receive/SendTo 收發。本文提供完整伺服器/客戶端/WinForms 三種整合方式,並指出生產環境應改用組播與可靠傳輸庫。掌握此基礎,即可擴充至即時遊戲同步、IoT 設備發現、日誌集中收集等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved