开发者

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

目录
  • 前言
  • 一、实现原理
  • 二、代码实现
  • 三、功能详解
    • 1、串口监听服务
    • 2、数据变化检测与转发
    • 3、TCP 连接管理
    • 4、错误处理与资源管理
  • 四、应用场景
    • 五、配置说明
      • 总结

        前言

        在工业自动化、物联网设备管理、远程监控等应用场景中,经常需要将本地串口设备(如条码扫描枪、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;
        
        namespace AppComTransTcp
        {
            internal class Program
            {
                // TCP客户端
                private static TcpClient _tcpClient;
                // 网络数据流
                private static NetworkStream _networkStream;
                // 串口对象
                private static SerialPort _serialPort;
                // TCP服务器IP地址
                private static string _serverIp = "127.0.0.1";
                // TCP服务器端口
                private static int _serverPort = 3001;
                // 串口名称
                private static string _portName = "COM1";
                // 波特率
                private static int _baudRate = 9600;
                // 数据位
                private static int _dataBits = 8;
                // 停止位
                private static StopBits _stopBits = StopBits.One;
                // 校验位
                private static Parity _parity = Parity.None;
                // 重连间隔(毫秒)
                private static int _reconnectInterval = 5000;
                // 是否继续运行
                private static bool _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
                    {
                        // 初始化串口
                        InitializeSeandroidrialPort();
                        // 初始化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 = new byte[_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 连接管理

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

        • 自动重连机制;
        • 定期检查连接状态;
        • 异常处理与连接恢复。

        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#实现串口监听与TCP转发功能的详细内容,更多关于C#串口监听与TCP转发的资料请关注编程客栈(www.devze.com)其它相关文章!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜