visual stdio中用C#,UDP协议写一个简陋的服务器
2026/7/2 4:21:39 网站建设 项目流程

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询