窗体1:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace UdpServerDemo
{
    public partial class Form1 : Form
    {
        private Socket udpServerSocket;
        private Thread listenThread;
        private bool isServerRunning = false;

        public Form1()
        {
            InitializeComponent();
        }

        // 启动UDP服务按钮1
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (!int.TryParse(txtPort.Text, out int port) || port < 1 || port > 65535)
            {
                MessageBox.Show("请输入合法端口");
                return;
            }

            try
            {
                // 创建UDP Socket
                udpServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                // 绑定本机所有网卡+指定端口
                IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port);
                udpServerSocket.Bind(endPoint);

                isServerRunning = true;
                // 新开线程循环接收数据(防止界面卡死)
                listenThread = new Thread(ReceiveLoop);
                listenThread.IsBackground = true;
                listenThread.Start();

                AppendLog($"UDP服务已启动,监听端口:{port}");
                btnStart.Enabled = false;
                btnStop.Enabled = true;
            }
            catch (Exception ex)
            {
                AppendLog($"启动失败:{ex.Message}");
            }
        }

        // 循环接收客户端数据
        private void ReceiveLoop()
        {
            byte[] buffer = new byte[1024 * 10]; 
            while (isServerRunning)
            {
                try
                {
                    // 存储客户端地址
                    IPEndPoint clientEp = new IPEndPoint(IPAddress.Any, 0);
                    EndPoint remoteEp = clientEp;

                    // 阻塞等待接收数据
                    int recvLen = udpServerSocket.ReceiveFrom(buffer, ref remoteEp);
                    clientEp = (IPEndPoint)remoteEp;

                    // 解析收到的字符串
                    string recvStr = Encoding.UTF8.GetString(buffer, 0, recvLen);
                    string clientInfo = $"{clientEp.Address}:{clientEp.Port}";

                    // 界面打印日志
                    Invoke(new Action(() =>
                    {
                        AppendLog($"[{clientInfo}] 收到:{recvStr}");
                    }));

                    // 给客户端回复消息
                    string response = $"服务端已收到你的消息:{recvStr}";
                    byte[] sendBuf = Encoding.UTF8.GetBytes(response);
                    udpServerSocket.SendTo(sendBuf, sendBuf.Length, SocketFlags.None, clientEp);

                    Invoke(new Action(() =>
                    {
                        AppendLog($"[{clientInfo}] 已回复:{response}");
                    }));
                }
                catch (SocketException)
                {
                    // 服务关闭时抛出异常,正常退出循环
                }
                catch (Exception ex)
                {
                    Invoke(new Action(() =>
                    {
                        AppendLog($"接收异常:{ex.Message}");
                    }));
                }
            }
        }

        // 停止服务按钮
        private void btnStop_Click(object sender, EventArgs e)
        {
            isServerRunning = false;
            udpServerSocket?.Close();
            listenThread?.Abort();

            AppendLog("UDP服务已停止");
            btnStart.Enabled = true;
            btnStop.Enabled = false;
        }

        // 追加日志到文本框
        private void AppendLog(string msg)
        {
            txtLog.AppendText($"{DateTime.Now:HH:mm:ss} {msg}\r\n");
            // 自动滚动到最后一行
            txtLog.SelectionStart = txtLog.TextLength;
            txtLog.ScrollToCaret();
        }

        // 窗口关闭时释放资源
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isServerRunning)
            {
                udpServerSocket?.Close();
                listenThread?.Abort();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //实例化客户端窗口
            Form2 clientForm = new Form2();
            clientForm.Show();
        }
    }
}

窗体2:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace UdpServerDemo
{
    public partial class Form2 : Form
    {
        // 单Socket同时负责发送、接收
        private Socket udpSocket;
        private Thread recvThread;
        private bool isRecving = false;

        public Form2()
        {
            InitializeComponent();
            // 创建UDP套接字并提前绑定随机本地端口,收发共用此端口
            udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint localBindEp = new IPEndPoint(IPAddress.Any, 0);
            udpSocket.Bind(localBindEp);
            // 初始关闭按钮不可点击
            btnStopRecv.Enabled = false;
        }

        // 开启后台持续接收线程
        private void btnStartRecv_Click(object sender, EventArgs e)
        {
            if (isRecving)
            {
                AppendLog("后台接收已开启,无需重复启动");
                return;
            }
            isRecving = true;
            recvThread = new Thread(ClientReceiveLoop);
            recvThread.IsBackground = true;
            recvThread.Start();

            AppendLog("✅ 客户端后台接收线程已启动");
            btnStartRecv.Enabled = false;
            btnStopRecv.Enabled = true;
        }

        // 后台循环接收服务端下发的数据
        private void ClientReceiveLoop()
        {
            byte[] buffer = new byte[1024 * 10];
            while (isRecving)
            {
                try
                {
                    EndPoint remoteEp = new IPEndPoint(IPAddress.Any, 0);
                    // 阻塞等待服务端消息
                    int recvLen = udpSocket.ReceiveFrom(buffer, ref remoteEp);
                    IPEndPoint serverEp = (IPEndPoint)remoteEp;
                    string msg = Encoding.UTF8.GetString(buffer, 0, recvLen);

                    Invoke(new Action(() =>
                    {
                        if (!this.IsDisposed)
                        {
                            AppendLog($"[来自 {serverEp.Address}:{serverEp.Port}] 收到:{msg}");
                        }
                    }));
                }
                catch (SocketException)
                {
                    // 仅停止接收时跳出循环
                    if (!isRecving)
                        break;
                }
                catch (Exception ex)
                {
                    Invoke(new Action(() =>
                    {
                        if (!this.IsDisposed)
                        {
                            AppendLog($"接收异常:{ex.Message}");
                        }
                    }));
                }
            }
        }

        // 发送消息到服务端
        private void btnSend_Click(object sender, EventArgs e)
        {
            // 1. 校验IP
            string ipStr = txtServerIP.Text.Trim();
            if (!IPAddress.TryParse(ipStr, out IPAddress serverIp))
            {
                AppendLog("❌ IP地址格式错误!");
                return;
            }
            // 2. 校验端口
            string portStr = txtServerPort.Text.Trim();
            if (!int.TryParse(portStr, out int port) || port < 1 || port > 65535)
            {
                AppendLog("❌ 端口必须是1~65535数字!");
                return;
            }
            // 3. 校验发送内容
            string sendContent = txtSendMsg.Text.Trim();
            if (string.IsNullOrEmpty(sendContent))
            {
                AppendLog("❌ 发送内容不能为空!");
                return;
            }

            IPEndPoint targetEp = new IPEndPoint(serverIp, port);
            byte[] sendBuf = Encoding.UTF8.GetBytes(sendContent);

            try
            {
                // 使用共用Socket发送
                udpSocket.SendTo(sendBuf, sendBuf.Length, SocketFlags.None, targetEp);
                AppendLog($"→ 发送至 {serverIp}:{port} 内容:{sendContent}");
                // 发送成功清空输入框并聚焦
                txtSendMsg.Clear();
                txtSendMsg.Focus();
            }
            catch (Exception ex)
            {
                AppendLog($"❌ 发送失败:{ex.Message}(检查服务端是否启动/防火墙拦截)");
            }
        }

        // 日志追加工具方法
        private void AppendLog(string info)
        {
            txtLog.AppendText($"{DateTime.Now:HH:mm:ss} {info}\r\n");
            txtLog.SelectionStart = txtLog.TextLength;
            txtLog.ScrollToCaret();
        }

        // 关闭后台接收
        private void btnStopRecv_Click(object sender, EventArgs e)
        {
            if (!isRecving)
            {
                AppendLog("当前未开启接收,无需关闭");
                return;
            }
            // 标记停止循环
            isRecving = false;
            // 等待线程安全结束
            recvThread?.Join(100);

            AppendLog("✅ 客户端后台接收已关闭");
            btnStartRecv.Enabled = true;
            btnStopRecv.Enabled = false;
        }

        // 窗口关闭释放资源
        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 先停止接收线程
            if (isRecving)
            {
                isRecving = false;
                recvThread?.Join(100);
            }
            // 程序退出再关闭套接字
            udpSocket?.Close();
        }
    }
}

更多推荐