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