编辑
2025-09-29
C#
00

目录

实现原理
完整代码实现
功能详解
1. 串口监听服务
2. 数据变化检测与转发
3. TCP连接管理
4. 错误处理与资源管理
应用场景
配置说明
总结

本文详细介绍如何使用C#创建串口监听服务,并将数据变化实时通过TCP转发到服务器。包含完整代码示例与实现思路,适合需要远程数据采集、工业设备监控的开发者参考。

在工业自动化、物联网设备管理、远程监控等应用场景中,经常需要将本地串口设备(如条码扫描枪、RFID读卡器、各类传感器)的数据实时传输到远程服务器进行处理。本文将详细讲解如何使用C#实现串口数据监听与TCP转发功能。

实现原理

我们的实现基于以下核心步骤:

  1. 创建串口监听服务,配置并打开串口
  2. 注册串口数据接收事件
  3. 当检测到串口数据变化时,通过TCP连接发送到远程服务器
  4. 实现稳定可靠的错误处理和重连机制

完整代码实现

下面是完整的C#代码实现,包含详细的中文注释:

C#
using System.IO.Ports; using System.Net.Sockets; using System.Text; 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 { // 初始化串口 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 = 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}"); } } } }

image.png

image.png

功能详解

1. 串口监听服务

程序通过SerialPort类实现串口监听,主要参数包括:

  • 串口名称(COM1、COM2等)
  • 波特率(常见如9600、115200等)
  • 数据位(通常为8位)
  • 停止位(通常为1位)
  • 校验位(通常为无校验)
C#
_serialPort = new SerialPort { PortName = _portName, BaudRate = _baudRate, DataBits = _dataBits, StopBits = _stopBits, Parity = _parity, ReadBufferSize = 4096, ReadTimeout = 500 };

2. 数据变化检测与转发

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

C#
_serialPort.DataReceived += SerialPort_DataReceived;

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

  1. 读取串口缓冲区数据
  2. 处理数据(可根据需求自定义数据处理逻辑)
  3. 调用SendDataToTcpServer方法将数据转发到TCP服务器

3. TCP连接管理

程序使用TcpClient类建立与TCP服务器的连接:

  • 自动重连机制确保网络临时中断后能够恢复连接
  • 定期检查连接状态,发现断开立即尝试重连
  • 优雅处理各种网络异常情况

4. 错误处理与资源管理

程序实现全面的错误处理机制:

  • 捕获并记录各阶段可能的异常
  • 确保资源正确释放,避免内存泄漏
  • 在程序退出时自动关闭串口和网络连接

应用场景

本解决方案适用于多种实际应用场景:

  1. 工业自动化:将现场设备数据(如PLC、传感器)实时传输到中央服务器
  2. 物联网设备管理:采集分散物联网设备数据进行集中处理
  3. 零售系统:将条码扫描枪数据实时传输到后台服务器
  4. 医疗设备:将医疗仪器数据实时传输到监控中心
  5. 仓储物流:实时追踪物流标签读取信息

配置说明

实际使用时,您需要根据需求修改以下配置:

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

总结

本文详细介绍了如何使用C#实现串口数据监听和TCP转发功能。通过合理的架构设计和完善的错误处理,该解决方案可以稳定可靠地工作在各种环境中。代码示例提供了完整的实现,您可以直接参考使用,也可以根据自己的需求进行定制和扩展。

对于需要将现场设备数据远程传输的场景,本文提供的解决方案可以作为基础框架,帮助您快速构建自己的数据采集和转发系统。


关键词:C#串口通信、TCP数据转发、SerialPort编程、C#网络编程、串口监听服务、工业数据采集、C#物联网开发

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!