最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于C#實現(xiàn)串口監(jiān)聽與TCP轉(zhuǎn)發(fā)功能

 更新時間:2025年06月09日 08:53:11   作者:小碼編匠  
在工業(yè)自動化、物聯(lián)網(wǎng)設(shè)備管理、遠(yuǎn)程監(jiān)控等應(yīng)用場景中,經(jīng)常需要將本地串口設(shè)備的數(shù)據(jù)實時傳輸?shù)竭h(yuǎn)程服務(wù)器進(jìn)行處理,本文將詳細(xì)介紹如何使用 C# 創(chuàng)建一個串口監(jiān)聽服務(wù),并將接收到的數(shù)據(jù)通過 TCP 協(xié)議轉(zhuǎn)發(fā)至遠(yuǎn)程服務(wù)器,需要的朋友可以參考下

前言

在工業(yè)自動化、物聯(lián)網(wǎng)設(shè)備管理、遠(yuǎn)程監(jiān)控等應(yīng)用場景中,經(jīng)常需要將本地串口設(shè)備(如條碼掃描槍、RFID讀卡器、各類傳感器)的數(shù)據(jù)實時傳輸?shù)竭h(yuǎn)程服務(wù)器進(jìn)行處理。本文將詳細(xì)介紹如何使用 C# 創(chuàng)建一個串口監(jiān)聽服務(wù),并將接收到的數(shù)據(jù)通過 TCP 協(xié)議轉(zhuǎn)發(fā)至遠(yuǎn)程服務(wù)器。

本方案實現(xiàn)的功能非常實用且簡潔:當(dāng)串口設(shè)備有數(shù)據(jù)輸入時,程序自動捕獲并將其轉(zhuǎn)發(fā)至指定的 TCP 服務(wù)器。適用于遠(yuǎn)程數(shù)據(jù)采集、設(shè)備狀態(tài)監(jiān)控、嵌入式系統(tǒng)通信等多種場景。

一、實現(xiàn)原理

整個程序基于以下核心步驟構(gòu)建:

1、創(chuàng)建串口監(jiān)聽服務(wù):配置并打開串口,注冊數(shù)據(jù)接收事件;

2、監(jiān)聽串口數(shù)據(jù)變化:通過 DataReceived 事件捕獲新數(shù)據(jù);

3、建立 TCP 連接:將接收到的數(shù)據(jù)通過 TCP 客戶端發(fā)送到遠(yuǎn)程服務(wù)器;

4、實現(xiàn)重連機(jī)制:在網(wǎng)絡(luò)異常中斷后自動嘗試重新連接;

5、資源釋放與異常處理:確保程序退出或異常時能正確關(guān)閉串口和網(wǎng)絡(luò)連接,避免資源泄漏。

二、代碼實現(xiàn)

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;
        // 網(wǎng)絡(luò)數(shù)據(jù)流
        private static NetworkStream _networkStream;
        // 串口對象
        private static SerialPort _serialPort;
        // TCP服務(wù)器IP地址
        private static string _serverIp = "127.0.0.1";
        // TCP服務(wù)器端口
        private static int _serverPort = 3001;
        // 串口名稱
        private static string _portName = "COM1";
        // 波特率
        private static int _baudRate = 9600;
        // 數(shù)據(jù)位
        private static int _dataBits = 8;
        // 停止位
        private static StopBits _stopBits = StopBits.One;
        // 校驗位
        private static Parity _parity = Parity.None;
        // 重連間隔(毫秒)
        private static int _reconnectInterval = 5000;
        // 是否繼續(xù)運行
        private static bool _isRunning = true;

        static void Main(string[] args)
        {
            Console.WriteLine("串口TCP轉(zhuǎn)發(fā)服務(wù)啟動中...");
            // 初始化并啟動服務(wù)
            InitializeService();
            Console.WriteLine("服務(wù)已啟動。按 'q' 退出程序。");

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

            // 關(guān)閉資源
            CloseConnections();
            Console.WriteLine("程序已退出。");
        }

        /// <summary>
        /// 初始化服務(wù),包括串口和TCP連接
        /// </summary>
        private static void InitializeService()
        {
            try
            {
                // 初始化串口
                InitializeSerialPort();
                // 初始化TCP連接
                ConnectToTcpServer();
                // 啟動重連檢查任務(wù)
                StartReconnectionTask();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"初始化服務(wù)失敗: {ex.Message}");
            }
        }

        /// <summary>
        /// 初始化串口設(shè)置
        /// </summary>
        private static void InitializeSerialPort()
        {
            try
            {
                // 創(chuàng)建并配置串口對象
                _serialPort = new SerialPort
                {
                    PortName = _portName,
                    BaudRate = _baudRate,
                    DataBits = _dataBits,
                    StopBits = _stopBits,
                    Parity = _parity,
                    ReadBufferSize = 4096,
                    ReadTimeout = 500
                };

                // 注冊數(shù)據(jù)接收事件
                _serialPort.DataReceived += SerialPort_DataReceived;

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

        /// <summary>
        /// 建立TCP服務(wù)器連接
        /// </summary>
        private static void ConnectToTcpServer()
        {
            try
            {
                // 創(chuàng)建TCP客戶端并連接服務(wù)器
                _tcpClient = new TcpClient();
                _tcpClient.Connect(_serverIp, _serverPort);
                _networkStream = _tcpClient.GetStream();
                Console.WriteLine($"已成功連接到TCP服務(wù)器 {_serverIp}:{_serverPort}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"連接TCP服務(wù)器失敗: {ex.Message}");
                // 這里不拋出異常,讓重連機(jī)制處理
            }
        }

        /// <summary>
        /// 啟動TCP重連檢查任務(wù)
        /// </summary>
        private static void StartReconnectionTask()
        {
            Task.Run(async () =>
            {
                while (_isRunning)
                {
                    try
                    {
                        // 檢查TCP連接狀態(tài)
                        if (_tcpClient == null || !_tcpClient.Connected)
                        {
                            Console.WriteLine("TCP連接已斷開,嘗試重新連接...");

                            // 關(guān)閉舊連接
                            if (_tcpClient != null)
                            {
                                _tcpClient.Close();
                                _tcpClient.Dispose();
                            }

                            // 創(chuàng)建新連接
                            ConnectToTcpServer();
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"重連過程發(fā)生錯誤: {ex.Message}");
                    }

                    // 等待指定時間后再次檢查
                    await Task.Delay(_reconnectInterval);
                }
            });
        }

        /// <summary>
        /// 串口數(shù)據(jù)接收事件處理
        /// </summary>
        private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                // 確保有足夠的數(shù)據(jù)可讀
                if (_serialPort.BytesToRead <= 0)
                    return;

                // 讀取串口數(shù)據(jù)
                byte[] buffer = new byte[_serialPort.BytesToRead];
                _serialPort.Read(buffer, 0, buffer.Length);

                // 轉(zhuǎn)換為字符串(可根據(jù)實際需求修改編碼方式)
                string data = Encoding.UTF8.GetString(buffer);
                Console.WriteLine($"接收到串口數(shù)據(jù): {data}");

                // 將數(shù)據(jù)轉(zhuǎn)發(fā)到TCP服務(wù)器
                SendDataToTcpServer(buffer);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"處理串口數(shù)據(jù)時發(fā)生錯誤: {ex.Message}");
            }
        }

        /// <summary>
        /// 發(fā)送數(shù)據(jù)到TCP服務(wù)器
        /// </summary>
        private static void SendDataToTcpServer(byte[] data)
        {
            try
            {
                // 檢查TCP連接是否可用
                if (_tcpClient != null && _tcpClient.Connected && _networkStream != null)
                {
                    // 發(fā)送數(shù)據(jù)
                    _networkStream.Write(data, 0, data.Length);
                    _networkStream.Flush();
                    Console.WriteLine($"已發(fā)送 {data.Length} 字節(jié)數(shù)據(jù)到TCP服務(wù)器");
                }
                else
                {
                    Console.WriteLine("TCP連接不可用,數(shù)據(jù)發(fā)送失敗");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"發(fā)送數(shù)據(jù)到TCP服務(wù)器失敗: {ex.Message}");

                // 標(biāo)記連接為斷開,讓重連機(jī)制處理
                if (_tcpClient != null)
                {
                    _tcpClient.Close();
                }
            }
        }

        /// <summary>
        /// 關(guān)閉所有連接并釋放資源
        /// </summary>
        private static void CloseConnections()
        {
            try
            {
                // 關(guān)閉串口
                if (_serialPort != null && _serialPort.IsOpen)
                {
                    _serialPort.DataReceived -= SerialPort_DataReceived;
                    _serialPort.Close();
                    _serialPort.Dispose();
                    Console.WriteLine("串口已關(guān)閉");
                }

                // 關(guān)閉TCP連接
                if (_networkStream != null)
                {
                    _networkStream.Close();
                    _networkStream.Dispose();
                }

                if (_tcpClient != null)
                {
                    _tcpClient.Close();
                    _tcpClient.Dispose();
                    Console.WriteLine("TCP連接已關(guān)閉");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"關(guān)閉連接時發(fā)生錯誤: {ex.Message}");
            }
        }
    }
}

三、功能詳解

1、串口監(jiān)聽服務(wù)

使用 SerialPort 類實現(xiàn)串口監(jiān)聽,支持自定義配置如下:

  • 串口名稱(如 COM1)
  • 波特率(如 9600、115200)
  • 數(shù)據(jù)位(通常為 8 位)
  • 停止位(通常為 1 位)
  • 校驗位(通常為無校驗)

示例配置:

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

2、數(shù)據(jù)變化檢測與轉(zhuǎn)發(fā)

通過注冊 DataReceived 事件實現(xiàn)串口數(shù)據(jù)變化檢測:

_serialPort.DataReceived += SerialPort_DataReceived;

當(dāng)串口接收到數(shù)據(jù)后,事件處理程序自動觸發(fā):

1、讀取緩沖區(qū)數(shù)據(jù);

2、將其轉(zhuǎn)換為字符串;

3、調(diào)用 SendDataToTcpServer 方法將數(shù)據(jù)轉(zhuǎn)發(fā)到 TCP 服務(wù)器。

3、TCP 連接管理

使用 TcpClientNetworkStream 建立與服務(wù)器的連接,并實現(xiàn)以下功能:

  • 自動重連機(jī)制;
  • 定期檢查連接狀態(tài);
  • 異常處理與連接恢復(fù)。

4、錯誤處理與資源管理

  • 全面捕獲各階段異常;
  • 在程序退出時優(yōu)雅關(guān)閉串口與網(wǎng)絡(luò)連接;
  • 防止內(nèi)存泄漏,確保資源正確釋放。

四、應(yīng)用場景

該解決方案適用于多種工業(yè)及物聯(lián)網(wǎng)場景,包括但不限于:

1、工業(yè)自動化:PLC、傳感器數(shù)據(jù)遠(yuǎn)程采集;

2、物聯(lián)網(wǎng)設(shè)備管理:邊緣設(shè)備數(shù)據(jù)集中上傳;

3、零售系統(tǒng):條碼掃描槍數(shù)據(jù)實時上傳;

4、醫(yī)療設(shè)備:儀器數(shù)據(jù)遠(yuǎn)程監(jiān)控;

5、倉儲物流:RFID 讀寫器數(shù)據(jù)同步。

五、配置說明

根據(jù)實際部署環(huán)境,需修改以下配置參數(shù):

private static string _serverIp = "192.168.1.100";   // 服務(wù)器IP
private static int _serverPort = 8080;              // 服務(wù)器端口
private static string _portName = "COM1";           // 串口名稱
private static int _baudRate = 9600;                // 波特率

總結(jié)

本文詳細(xì)講解了如何使用 C# 實現(xiàn)串口監(jiān)聽與 TCP 轉(zhuǎn)發(fā)功能。該方案結(jié)構(gòu)清晰、功能完整,具備良好的穩(wěn)定性和可擴(kuò)展性。你可以直接使用本示例作為基礎(chǔ)模塊,也可以根據(jù)具體業(yè)務(wù)需求進(jìn)行定制開發(fā)。

對于需要遠(yuǎn)程采集串口設(shè)備數(shù)據(jù)的應(yīng)用場景,該程序提供了一個輕量但高效的解決方案。無論是工業(yè)現(xiàn)場設(shè)備監(jiān)控,還是物聯(lián)網(wǎng)終端數(shù)據(jù)上傳,都能從中受益。

以上就是基于C#實現(xiàn)串口監(jiān)聽與TCP轉(zhuǎn)發(fā)功能的詳細(xì)內(nèi)容,更多關(guān)于C#串口監(jiān)聽與TCP轉(zhuǎn)發(fā)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Unity 如何批量修改FBX模型

    Unity 如何批量修改FBX模型

    這篇文章主要介紹了Unity 批量修改FBX模型的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C#中JSON轉(zhuǎn)為實體類和List以及結(jié)合使用

    C#中JSON轉(zhuǎn)為實體類和List以及結(jié)合使用

    開發(fā)中經(jīng)常遇到將JSON字符串轉(zhuǎn)換為List的需求,下面這篇文章主要給大家介紹了關(guān)于C#中JSON轉(zhuǎn)為實體類和List以及結(jié)合使用的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • C#中Cookie之存儲對象

    C#中Cookie之存儲對象

    這篇文章主要介紹了在項目中,需要將用戶的信息存到Cookie中,但是cookie只能保存字符串,所以需要先序列號,然后在存儲在cookie中,有需要的朋友可以借鑒下
    2015-07-07
  • C# null 合并運算符??(雙問號)使用示例

    C# null 合并運算符??(雙問號)使用示例

    這篇文章主要介紹了C# null 合并運算符??(雙問號)使用示例,?? 運算符稱作 null 合并運算符。如果此運算符的左操作數(shù)不為 null,則此運算符將返回左操作數(shù);否則返回右操作數(shù),需要的朋友可以參考下
    2014-06-06
  • 登錄驗證全局控制的幾種方式總結(jié)(session)

    登錄驗證全局控制的幾種方式總結(jié)(session)

    在登陸驗證或者其他需要用到session全局變量的時候,歸結(jié)起來,主要有以下三種較方便的實現(xiàn)方式。(其中個人較喜歡使用第一種實現(xiàn)方法)
    2014-01-01
  • 基于WinForm+Halcon實現(xiàn)圖像縮放與交互功能

    基于WinForm+Halcon實現(xiàn)圖像縮放與交互功能

    本文主要講述在 WinForm 中結(jié)合 Halcon 實現(xiàn)圖像縮放、平移及實時顯示灰度值等交互功能,包括初始化窗口的不同方式,以及通過特定事件添加相應(yīng)功能的詳細(xì)步驟和代碼示例,能提升圖像處理應(yīng)用的開發(fā)效率和用戶體驗,需要的朋友可以參考下
    2025-01-01
  • 詳解C#中的依賴注入和IoC容器

    詳解C#中的依賴注入和IoC容器

    這篇文章主要介紹了C#中的依賴注入和IoC容器的相關(guān)資料,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2020-12-12
  • C#使用偽隨機(jī)數(shù)實現(xiàn)加密用戶密碼的方法

    C#使用偽隨機(jī)數(shù)實現(xiàn)加密用戶密碼的方法

    這篇文章主要介紹了C#使用偽隨機(jī)數(shù)實現(xiàn)加密用戶密碼的方法,對于開發(fā)C#會員系統(tǒng)或者程序安全問題都有一定的參考借鑒價值,需要的朋友可以參考下
    2014-07-07
  • WPF自定義MenuItem樣式的實現(xiàn)方法

    WPF自定義MenuItem樣式的實現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于WPF自定義MenuItem樣式的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用WPF具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • C# SQLite事務(wù)操作方法分析

    C# SQLite事務(wù)操作方法分析

    這篇文章主要介紹了C# SQLite事務(wù)操作方法,簡單分析了使用SQL代碼及C#代碼實現(xiàn)事務(wù)功能的操作技巧,需要的朋友可以參考下
    2017-07-07

最新評論

吐鲁番市| 建德市| 双流县| 项城市| 丹棱县| 漳浦县| 河池市| 贺州市| 全州县| 古浪县| 铜鼓县| 岳阳市| 普洱| 永泰县| 阳江市| 阳曲县| 鹤庆县| 普宁市| 柘荣县| 湖州市| 峨山| 榆社县| 鄂温| 红安县| 察雅县| 乌兰县| 马鞍山市| 临泽县| 赤水市| 水城县| 改则县| 阿拉善左旗| 额敏县| 海兴县| 新绛县| 昌黎县| 永登县| 玉树县| 德令哈市| 邵东县| 安阳县|