LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 实现串口监听与 TCP 转发功能

admin
2025年7月6日 8:47 本文热度 46

前言

在工业自动化、物联网设备管理、远程监控等应用场景中,经常需要将本地串口设备(如条码扫描枪、RFID读卡器、各类传感器)的数据实时传输到远程服务器进行处理。本文将详细介绍如何使用 C# 创建一个串口监听服务,并将接收到的数据通过 TCP 协议转发至远程服务器。

本方案实现的功能非常实用且简洁:当串口设备有数据输入时,程序自动捕获并将其转发至指定的 TCP 服务器。适用于远程数据采集、设备状态监控、嵌入式系统通信等多种场景。

正文

一、实现原理

整个程序基于以下核心步骤构建:

1、创建串口监听服务:配置并打开串口,注册数据接收事件;

2、监听串口数据变化:通过 DataReceived 事件捕获新数据;

3、建立 TCP 连接:将接收到的数据通过 TCP 客户端发送到远程服务器;

4、实现重连机制:在网络异常中断后自动尝试重新连接;

5、资源释放与异常处理:确保程序退出或异常时能正确关闭串口和网络连接,避免资源泄漏。

二、代码实现

using System;
using System.IO.Ports;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespaceAppComTransTcp
{
    internalclassProgram
    {
        // TCP客户端
        privatestatic TcpClient _tcpClient;
        // 网络数据流
        privatestatic NetworkStream _networkStream;
        // 串口对象
        privatestatic SerialPort _serialPort;
        // TCP服务器IP地址
        privatestaticstring _serverIp = "127.0.0.1";
        // TCP服务器端口
        privatestaticint _serverPort = 3001;
        // 串口名称
        privatestaticstring _portName = "COM1";
        // 波特率
        privatestaticint _baudRate = 9600;
        // 数据位
        privatestaticint _dataBits = 8;
        // 停止位
        privatestatic StopBits _stopBits = StopBits.One;
        // 校验位
        privatestatic Parity _parity = Parity.None;
        // 重连间隔(毫秒)
        privatestaticint _reconnectInterval = 5000;
        // 是否继续运行
        privatestaticbool _isRunning = true;

        static void Main(string[] args)
        {
            Console.WriteLine("串口TCP转发服务启动中...");
            // 初始化并启动服务
            InitializeService();
            Console.WriteLine("服务已启动。按 'q' 退出程序。");

            // 保持程序运行,直到用户输入q退出
            while (_isRunning)
            {
                var key = Console.ReadKey(true);
                if (key.KeyChar == 'q' || key.KeyChar == 'Q')
                {
                    _isRunning = false;
                }
            }

            // 关闭资源
            CloseConnections();
            Console.WriteLine("程序已退出。");
        }

        /// <summary>
        /// 初始化服务,包括串口和TCP连接
        /// </summary>
        private static void InitializeService()
        {
            try
            {
                // 初始化串口
                InitializeSerialPort();
                // 初始化TCP连接
                ConnectToTcpServer();
                // 启动重连检查任务
                StartReconnectionTask();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"初始化服务失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 初始化串口设置
        /// </summary>
        private static void InitializeSerialPort()
        {
            try
            {
                // 创建并配置串口对象
                _serialPort = new SerialPort
                {
                    PortName = _portName,
                    BaudRate = _baudRate,
                    DataBits = _dataBits,
                    StopBits = _stopBits,
                    Parity = _parity,
                    ReadBufferSize = 4096,
                    ReadTimeout = 500
                };

                // 注册数据接收事件
                _serialPort.DataReceived += SerialPort_DataReceived;

                // 打开串口
                _serialPort.Open();
                Console.WriteLine($"串口 {_portName} 已成功打开,波特率: {_baudRate}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"初始化串口失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 建立TCP服务器连接
        /// </summary>
        private static void ConnectToTcpServer()
        {
            try
            {
                // 创建TCP客户端并连接服务器
                _tcpClient = new TcpClient();
                _tcpClient.Connect(_serverIp, _serverPort);
                _networkStream = _tcpClient.GetStream();
                Console.WriteLine($"已成功连接到TCP服务器 {_serverIp}:{_serverPort}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"连接TCP服务器失败: {ex.Message}");
                // 这里不抛出异常,让重连机制处理
            }
        }

        /// <summary>
        /// 启动TCP重连检查任务
        /// </summary>
        private static void StartReconnectionTask()
        {
            Task.Run(async () =>
            {
                while (_isRunning)
                {
                    try
                    {
                        // 检查TCP连接状态
                        if (_tcpClient == null || !_tcpClient.Connected)
                        {
                            Console.WriteLine("TCP连接已断开,尝试重新连接...");

                            // 关闭旧连接
                            if (_tcpClient != null)
                            {
                                _tcpClient.Close();
                                _tcpClient.Dispose();
                            }

                            // 创建新连接
                            ConnectToTcpServer();
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"重连过程发生错误: {ex.Message}");
                    }

                    // 等待指定时间后再次检查
                    await Task.Delay(_reconnectInterval);
                }
            });
        }

        /// <summary>
        /// 串口数据接收事件处理
        /// </summary>
        private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                // 确保有足够的数据可读
                if (_serialPort.BytesToRead <= 0)
                    return;

                // 读取串口数据
                byte[] buffer = newbyte[_serialPort.BytesToRead];
                _serialPort.Read(buffer, 0, buffer.Length);

                // 转换为字符串(可根据实际需求修改编码方式)
                string data = Encoding.UTF8.GetString(buffer);
                Console.WriteLine($"接收到串口数据: {data}");

                // 将数据转发到TCP服务器
                SendDataToTcpServer(buffer);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"处理串口数据时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 发送数据到TCP服务器
        /// </summary>
        private static void SendDataToTcpServer(byte[] data)
        {
            try
            {
                // 检查TCP连接是否可用
                if (_tcpClient != null && _tcpClient.Connected && _networkStream != null)
                {
                    // 发送数据
                    _networkStream.Write(data, 0, data.Length);
                    _networkStream.Flush();
                    Console.WriteLine($"已发送 {data.Length} 字节数据到TCP服务器");
                }
                else
                {
                    Console.WriteLine("TCP连接不可用,数据发送失败");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送数据到TCP服务器失败: {ex.Message}");

                // 标记连接为断开,让重连机制处理
                if (_tcpClient != null)
                {
                    _tcpClient.Close();
                }
            }
        }

        /// <summary>
        /// 关闭所有连接并释放资源
        /// </summary>
        private static void CloseConnections()
        {
            try
            {
                // 关闭串口
                if (_serialPort != null && _serialPort.IsOpen)
                {
                    _serialPort.DataReceived -= SerialPort_DataReceived;
                    _serialPort.Close();
                    _serialPort.Dispose();
                    Console.WriteLine("串口已关闭");
                }

                // 关闭TCP连接
                if (_networkStream != null)
                {
                    _networkStream.Close();
                    _networkStream.Dispose();
                }

                if (_tcpClient != null)
                {
                    _tcpClient.Close();
                    _tcpClient.Dispose();
                    Console.WriteLine("TCP连接已关闭");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"关闭连接时发生错误: {ex.Message}");
            }
        }
    }
}

三、功能详解

1、串口监听服务

使用 SerialPort 类实现串口监听,支持自定义配置如下:

  • 串口名称(如 COM1)

  • 波特率(如 9600、115200)

  • 数据位(通常为 8 位)

  • 停止位(通常为 1 位)

  • 校验位(通常为无校验)

示例配置:

_serialPort = new SerialPort
{
    PortName = _portName,
    BaudRate = _baudRate,
    DataBits = _dataBits,
    StopBits = _stopBits,
    Parity = _parity,
    ReadBufferSize = 4096,
    ReadTimeout = 500
};

2、数据变化检测与转发

通过注册 DataReceived 事件实现串口数据变化检测:

_serialPort.DataReceived += SerialPort_DataReceived;

当串口接收到数据后,事件处理程序自动触发:

1、读取缓冲区数据;

2、将其转换为字符串;

3、调用 SendDataToTcpServer 方法将数据转发到 TCP 服务器。

3、TCP 连接管理

使用 TcpClient 和 NetworkStream 建立与服务器的连接,并实现以下功能:

  • 自动重连机制;

  • 定期检查连接状态;

  • 异常处理与连接恢复。

4、错误处理与资源管理

  • 全面捕获各阶段异常;

  • 在程序退出时优雅关闭串口与网络连接;

  • 防止内存泄漏,确保资源正确释放。

四、应用场景

该解决方案适用于多种工业及物联网场景,包括但不限于:

1、工业自动化:PLC、传感器数据远程采集;

2、物联网设备管理:边缘设备数据集中上传;

3、零售系统:条码扫描枪数据实时上传;

4、医疗设备:仪器数据远程监控;

5、仓储物流:RFID 读写器数据同步。

五、配置说明

根据实际部署环境,需修改以下配置参数:

private static string _serverIp = "192.168.1.100";   // 服务器IP
private static int _serverPort = 8080;              // 服务器端口
private static string _portName = "COM1";           // 串口名称
private static int _baudRate = 9600;                // 波特率

总结

本文详细讲解了如何使用 C# 实现串口监听与 TCP 转发功能。该方案结构清晰、功能完整,具备良好的稳定性和可扩展性。你可以直接使用本示例作为基础模块,也可以根据具体业务需求进行定制开发。

对于需要远程采集串口设备数据的应用场景,该程序提供了一个轻量但高效的解决方案。无论是工业现场设备监控,还是物联网终端数据上传,都能从中受益。

关键词

C#、#串口通信#SerialPort#TCP转发、DataReceived事件、TcpClient、NetworkStream、自动重连、错误处理、资源释放、#工业自动化#物联网#远程监控#条码扫描枪#RFID读卡器#传感器数据采集#数据上传#嵌入式系统通信#Socket编程、数据转发服务

最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号[DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

作者:技术老小子

出处:mp.weixin.qq.com/s/s8DYBrQGcsP3YEIARJ9rFg
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!


该文章在 2025/7/7 11:34:39 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved