You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForm中UdpClient连续接收UDP数据及字符串处理求助

问题根因

原代码仅单次调用UdpClient.Receive()阻塞方法,读取到1个UDP数据包后就结束执行,没有实现持续监听逻辑;且监听逻辑直接运行在UI主线程,长时间运行会直接导致界面无响应。

实现步骤
  • 将UdpClient声明为窗体内的全局变量,方便启动/停止时统一管理资源,避免泄漏
  • 点击启动按钮后,在后台线程执行循环监听逻辑,杜绝阻塞UI线程
  • 循环内持续调用Receive()方法读取6009端口的数据包,直到手动触发停止
  • 对读取到的字符串做格式修正:将单独的回车符(CR,\r)替换为标准回车换行(CRLF,\r\n),同时做兼容处理避免重复替换已符合规范的CRLF内容
  • 跨线程更新UI内容时使用控件的Invoke方法做线程安全调用,避免WinForm跨线程访问异常
  • 格式修正完成的字符串可直接通过UDP发送给对接的目标软件
完整修改代码
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        // 全局UDP客户端、监听线程、运行控制标记
        private UdpClient _udpClient;
        private Thread _listenThread;
        private bool _isListening = false;
        // 请修改为实际对接软件的监听IP和端口
        private readonly IPEndPoint _forwardTarget = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7001);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 初始化UDP客户端监听6009端口
            _udpClient = new UdpClient(6009);
            _isListening = true;
            // 启动后台线程跑监听逻辑
            _listenThread = new Thread(ReceiveLoop)
            {
                IsBackground = true
            };
            _listenThread.Start();

            // 更新控件状态
            button1.Enabled = false;
            textBox1.Enabled = false;
            textBox3.Enabled = false;
            button3.Enabled = true;
        }

        private void ReceiveLoop()
        {
            IPEndPoint remoteEp = new IPEndPoint(IPAddress.Any, 0);
            try
            {
                while (_isListening)
                {
                    // 阻塞等待接收UDP数据包
                    byte[] receiveBytes = _udpClient.Receive(ref remoteEp);
                    string rawData = Encoding.ASCII.GetString(receiveBytes);
                    
                    // 字符串格式化:CR后插入LF,避免重复替换已有的CRLF
                    string formattedData = rawData.Replace("\r\n", "\0").Replace("\r", "\r\n").Replace("\0", "\r\n");

                    // 转发格式化后的数据到对接软件
                    byte[] forwardBytes = Encoding.ASCII.GetBytes(formattedData);
                    _udpClient.Send(forwardBytes, forwardBytes.Length, _forwardTarget);

                    // 线程安全更新界面显示
                    UpdateUIDisplay(formattedData);
                }
            }
            catch (SocketException)
            {
                // 主动关闭客户端触发的异常无需处理
            }
            finally
            {
                _udpClient?.Close();
            }
        }

        private void UpdateUIDisplay(string content)
        {
            if (label2.InvokeRequired)
            {
                Invoke(new Action<string>(UpdateUIDisplay), content);
                return;
            }
            label2.Text = content;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // 停止监听逻辑
            _isListening = false;
            _udpClient?.Close();
            _listenThread?.Join(1000);

            // 恢复控件状态
            button1.Enabled = true;
            textBox1.Enabled = true;
            textBox3.Enabled = true;
            button3.Enabled = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 窗口关闭时主动释放资源,避免后台进程残留
            _isListening = false;
            _udpClient?.Close();
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            button3.Enabled = false;
        }

        private void button2_Click(object sender, EventArgs e)
        {

        }
    }
}
注意事项
  • 代码中_forwardTarget参数需要替换为实际对接软件的监听地址和端口
  • 若接收的NMEA定位数据存在分包、粘包情况,可自行添加内存缓冲区,拼接完完整语句后再做格式化和转发
  • 监听线程设置为后台线程,避免窗口关闭后程序进程仍在后台驻留
  • 停止监听时主动关闭UdpClient,可立刻中断阻塞的Receive()方法,快速退出监听循环

内容的提问来源于stack exchange,提问作者Marcelogeo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:57:49