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

C#實現(xiàn)串口通信的四種靈活策略和避坑指南

 更新時間:2026年01月06日 09:30:20   作者:小碼編匠  
這篇文章主要為大家詳細介紹了C#實現(xiàn)串口通信的四種靈活策略和避坑的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

前言

工業(yè)控制、物聯(lián)網(wǎng)設(shè)備通信中,是否遇到過這樣的場景:向設(shè)備發(fā)送一個簡單的查詢指令,卻發(fā)現(xiàn)返回的數(shù)據(jù)總是"分批到達"?明明應(yīng)該收到完整的20字節(jié)響應(yīng),卻只能收到幾個零散的數(shù)據(jù)包?

別急,這不是你的代碼有問題!

這是串口通信中最常見的"分包接收"現(xiàn)象。設(shè)備可能一次發(fā)送10字節(jié),下一次發(fā)送剩余的10字節(jié),而我們的程序卻不知道什么時候才算接收完成。

今天我們就來徹底解決這個讓無數(shù) C# 開發(fā)頭疼的問題!

為什么會分包接收

根本原因

串口通信是異步的,數(shù)據(jù)傳輸會受到以下因素影響:

硬件緩沖區(qū)大小限制

設(shè)備處理速度差異

網(wǎng)絡(luò)延遲(對于串口轉(zhuǎn)以太網(wǎng)設(shè)備)

系統(tǒng)調(diào)度

這些因素導(dǎo)致原本連續(xù)的數(shù)據(jù)流被 操作系統(tǒng)或中間設(shè)備拆分成多個小塊,逐次送達應(yīng)用程序。

傳統(tǒng)方案的痛點

// ? 錯誤示例:只能收到第一包數(shù)據(jù)
serialPort.Write(command, 0, command.Length);
Thread.Sleep(100); // 固定等待時間
byte[] buffer = new byte[1024];
int count = serialPort.Read(buffer, 0, 1024); // 可能只讀到部分數(shù)據(jù)

這種寫法的問題包括:

固定等待時間不可靠

無法判斷數(shù)據(jù)是否接收完整

容易丟失后續(xù)數(shù)據(jù)包

四種靈活接收策略

為應(yīng)對不同應(yīng)用場景,我們設(shè)計了以下四種策略:

方案一:數(shù)據(jù)間隔超時判斷(?推薦)

適用場景:不知道數(shù)據(jù)長度,但設(shè)備發(fā)送完畢后會有明顯時間間隔。

public byte[] SendQueryWithGapTimeout(byte[] command, int gapTimeoutMs = 100, int maxWaitMs = 3000)
{
    // 清空緩沖區(qū)并開始接收
    lock (bufferLock)
    {
        receivedBuffer.Clear();
        isWaitingForResponse = true;
        lastReceiveTime = DateTime.Now;
    }
    // 發(fā)送指令
    serialPort.Write(command, 0, command.Length);
    
    DateTime startTime = DateTime.Now;
    
    while ((DateTime.Now - startTime).TotalMilliseconds < maxWaitMs)
    {
        Thread.Sleep(10);
        
        lock (bufferLock)
        {
            // ?? 關(guān)鍵邏輯:有數(shù)據(jù)且間隔超時則認為接收完成
            if (receivedBuffer.Count > 0 && 
                (DateTime.Now - lastReceiveTime).TotalMilliseconds > gapTimeoutMs)
            {
                isWaitingForResponse = false;
                return receivedBuffer.ToArray();
            }
        }
    }
    
    return null;
}

實際業(yè)務(wù)中,這個能解決大部分問題。

方案二:結(jié)束符判斷

適用場景:數(shù)據(jù)以特定字符結(jié)尾(如 \r\n\0 等)。

public byte[] SendQueryWithEndMarker(byte[] command, byte[] endMarker, int maxWaitMs = 3000)
{
    // ... 發(fā)送邏輯相同 ...
    
    while ((DateTime.Now - startTime).TotalMilliseconds < maxWaitMs)
    {
        lock (bufferLock)
        {
            if (receivedBuffer.Count >= endMarker.Length)
            {
                // ?? 檢查緩沖區(qū)末尾是否包含結(jié)束標記
                bool foundEndMarker = true;
                for (int i = 0; i < endMarker.Length; i++)
                {
                    if (receivedBuffer[receivedBuffer.Count - endMarker.Length + i] != endMarker[i])
                    {
                        foundEndMarker = false;
                        break;
                    }
                }
                
                if (foundEndMarker)
                {
                    return receivedBuffer.ToArray();
                }
            }
        }
    }
}

方案三:協(xié)議幀結(jié)構(gòu)判斷

適用場景:數(shù)據(jù)有固定幀頭和長度字段(如 Modbus 協(xié)議)。

public byte[] SendQueryWithFrameProtocol(byte[] command, byte frameHeader, int lengthFieldOffset, int lengthFieldSize = 1)
{
    // ... 發(fā)送邏輯 ...
    
    while (/* 超時檢查 */)
    {
        lock (bufferLock)
        {
            if (receivedBuffer.Count > lengthFieldOffset + lengthFieldSize)
            {
                // 檢查幀頭
                if (receivedBuffer[0] == frameHeader)
                {
                    // ?? 從長度字段獲取數(shù)據(jù)長度
                    int dataLength = lengthFieldSize == 1 ? 
                        receivedBuffer[lengthFieldOffset] : 
                        (receivedBuffer[lengthFieldOffset] << 8) | receivedBuffer[lengthFieldOffset + 1];
                    
                    int expectedFrameLength = lengthFieldOffset + lengthFieldSize + dataLength;
                    
                    if (receivedBuffer.Count >= expectedFrameLength)
                    {
                        return receivedBuffer.Take(expectedFrameLength).ToArray();
                    }
                }
            }
        }
    }
}

方案四:組合策略(??推薦)

最靈活的方案,同時使用多種判斷條件:

public byte[] SendQueryWithCombinedStrategy(byte[] command,
    int gapTimeoutMs = 100,     // 數(shù)據(jù)間隔超時
    byte[] endMarker = null,    // 結(jié)束標記  
    int? maxLength = null,      // 最大長度限制
    int maxWaitMs = 3000)       // 總超時時間
{
    // ... 發(fā)送邏輯 ...
    
    while (/* 總超時檢查 */)
    {
        lock (bufferLock)
        {
            if (receivedBuffer.Count == 0) continue;
            
            // ?? 條件1:達到最大長度限制
            if (maxLength.HasValue && receivedBuffer.Count >= maxLength.Value)
                return receivedBuffer.ToArray();
            
            // ?? 條件2:發(fā)現(xiàn)結(jié)束標記
            if (endMarker != null && /* 檢查結(jié)束標記邏輯 */)
                return receivedBuffer.ToArray();
            
            // ?? 條件3:數(shù)據(jù)間隔超時
            if ((DateTime.Now - lastReceiveTime).TotalMilliseconds > gapTimeoutMs)
                return receivedBuffer.ToArray();
        }
    }
}

核心機制:數(shù)據(jù)接收事件

所有策略都依賴于統(tǒng)一的數(shù)據(jù)接收事件處理:

private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if (!isWaitingForResponse) return;
    try
    {
        int bytesToRead = serialPort.BytesToRead;
        if (bytesToRead > 0)
        {
            byte[] buffer = new byte[bytesToRead];
            int bytesRead = serialPort.Read(buffer, 0, bytesToRead);
            lock (bufferLock)
            {
                receivedBuffer.AddRange(buffer);
                lastReceiveTime = DateTime.Now; // ?? 更新最后接收時間
                Console.WriteLine($"收到數(shù)據(jù)包 ({bytesRead} 字節(jié)): {BitConverter.ToString(buffer, 0, bytesRead)}");
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"數(shù)據(jù)接收異常: {ex.Message}");
    }
}

完整代碼

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppFlexSerialPort
{
    internal class FlexibleSerialPort
    {
        private SerialPort serialPort;
        private List<byte> receivedBuffer;
        private readonly object bufferLock = new object();
        private Timer timeoutTimer;
        private bool isWaitingForResponse = false;
        private DateTime lastReceiveTime;
        private readonly int dataGapTimeout = 100; // 數(shù)據(jù)間隔超時時間(ms)

        public FlexibleSerialPort()
        {
            receivedBuffer = new List<byte>();
        }

        /// <summary>
        /// 初始化串口
        /// </summary>
        public bool InitializePort(string portName = "COM1", int baudRate = 9600,
            Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
        {
            try
            {
                serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                serialPort.ReadTimeout = 1000;
                serialPort.WriteTimeout = 1000;
                serialPort.DataReceived += OnDataReceived;
                serialPort.Open();
                Console.WriteLine($"串口 {portName} 已成功打開");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"串口初始化失敗: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 方案1: 基于數(shù)據(jù)間隔超時判斷接收完成
        /// 適用于:不知道數(shù)據(jù)長度,但設(shè)備發(fā)送完后會有明顯的時間間隔
        /// </summary>
        public byte[] SendQueryWithGapTimeout(byte[] command, int gapTimeoutMs = 100, int maxWaitMs = 3000)
        {
            if (serialPort == null || !serialPort.IsOpen)
            {
                Console.WriteLine("串口未打開");
                return null;
            }
            lock (bufferLock)
            {
                receivedBuffer.Clear();
                isWaitingForResponse = true;
                lastReceiveTime = DateTime.Now;
            }
            try
            {
                // 發(fā)送查詢指令
                serialPort.Write(command, 0, command.Length);
                Console.WriteLine($"已發(fā)送查詢指令: {BitConverter.ToString(command)}");
                DateTime startTime = DateTime.Now;
                DateTime lastCheckTime = DateTime.Now;
                int lastBufferSize = 0;
                while ((DateTime.Now - startTime).TotalMilliseconds < maxWaitMs)
                {
                    Thread.Sleep(10);
                    lock (bufferLock)
                    {
                        // 如果有數(shù)據(jù)且數(shù)據(jù)間隔超過指定時間,認為接收完成
                        if (receivedBuffer.Count > 0 &&
                            (DateTime.Now - lastReceiveTime).TotalMilliseconds > gapTimeoutMs)
                        {
                            isWaitingForResponse = false;
                            byte[] result = receivedBuffer.ToArray();
                            Console.WriteLine($"基于間隔超時判斷接收完成,共收到 {result.Length} 字節(jié)");
                            return result;
                        }
                    }
                }
                // 最大等待時間超時
                isWaitingForResponse = false;
                lock (bufferLock)
                {
                    if (receivedBuffer.Count > 0)
                    {
                        byte[] result = receivedBuffer.ToArray();
                        Console.WriteLine($"最大等待時間超時,收到 {result.Length} 字節(jié)");
                        return result;
                    }
                }
                Console.WriteLine("接收超時,未收到任何數(shù)據(jù)");
                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"發(fā)送指令失敗: {ex.Message}");
                isWaitingForResponse = false;
                return null;
            }
        }

        /// <summary>
        /// 方案2: 基于結(jié)束符判斷接收完成
        /// 適用于:數(shù)據(jù)以特定字符或字節(jié)序列結(jié)尾
        /// </summary>
        public byte[] SendQueryWithEndMarker(byte[] command, byte[] endMarker, int maxWaitMs = 3000)
        {
            if (serialPort == null || !serialPort.IsOpen)
            {
                Console.WriteLine("串口未打開");
                return null;
            }
            lock (bufferLock)
            {
                receivedBuffer.Clear();
                isWaitingForResponse = true;
            }
            try
            {
                serialPort.Write(command, 0, command.Length);
                Console.WriteLine($"已發(fā)送查詢指令: {BitConverter.ToString(command)}");
                DateTime startTime = DateTime.Now;
                while ((DateTime.Now - startTime).TotalMilliseconds < maxWaitMs)
                {
                    Thread.Sleep(10);
                    lock (bufferLock)
                    {
                        if (receivedBuffer.Count >= endMarker.Length)
                        {
                            // 檢查緩沖區(qū)末尾是否包含結(jié)束標記
                            bool foundEndMarker = true;
                            for (int i = 0; i < endMarker.Length; i++)
                            {
                                if (receivedBuffer[receivedBuffer.Count - endMarker.Length + i] != endMarker[i])
                                {
                                    foundEndMarker = false;
                                    break;
                                }
                            }
                            if (foundEndMarker)
                            {
                                isWaitingForResponse = false;
                                byte[] result = receivedBuffer.ToArray();
                                Console.WriteLine($"發(fā)現(xiàn)結(jié)束標記,接收完成,共收到 {result.Length} 字節(jié)");
                                return result;
                            }
                        }
                    }
                }
                // 超時處理
                isWaitingForResponse = false;
                lock (bufferLock)
                {
                    if (receivedBuffer.Count > 0)
                    {
                        byte[] result = receivedBuffer.ToArray();
                        Console.WriteLine($"等待結(jié)束標記超時,收到 {result.Length} 字節(jié)");
                        return result;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"發(fā)送指令失敗: {ex.Message}");
                isWaitingForResponse = false;
                return null;
            }
        }

        /// <summary>
        /// 方案3: 基于協(xié)議幀結(jié)構(gòu)判斷接收完成
        /// 適用于:數(shù)據(jù)有固定的幀頭和長度字段
        /// </summary>
        public byte[] SendQueryWithFrameProtocol(byte[] command, byte frameHeader, int lengthFieldOffset,
            int lengthFieldSize = 1, int maxWaitMs = 3000)
        {
            if (serialPort == null || !serialPort.IsOpen)
            {
                Console.WriteLine("串口未打開");
                return null;
            }
            lock (bufferLock)
            {
                receivedBuffer.Clear();
                isWaitingForResponse = true;
            }
            try
            {
                serialPort.Write(command, 0, command.Length);
                Console.WriteLine($"已發(fā)送查詢指令: {BitConverter.ToString(command)}");
                DateTime startTime = DateTime.Now;
                while ((DateTime.Now - startTime).TotalMilliseconds < maxWaitMs)
                {
                    Thread.Sleep(10);
                    lock (bufferLock)
                    {
                        if (receivedBuffer.Count > lengthFieldOffset + lengthFieldSize)
                        {
                            // 檢查幀頭
                            if (receivedBuffer[0] == frameHeader)
                            {
                                // 獲取數(shù)據(jù)長度
                                int dataLength = 0;
                                if (lengthFieldSize == 1)
                                {
                                    dataLength = receivedBuffer[lengthFieldOffset];
                                }
                                else if (lengthFieldSize == 2)
                                {
                                    dataLength = (receivedBuffer[lengthFieldOffset] << 8) | receivedBuffer[lengthFieldOffset + 1];
                                }
                                int expectedFrameLength = lengthFieldOffset + lengthFieldSize + dataLength;
                                if (receivedBuffer.Count >= expectedFrameLength)
                                {
                                    isWaitingForResponse = false;
                                    byte[] result = receivedBuffer.Take(expectedFrameLength).ToArray();
                                    Console.WriteLine($"根據(jù)幀長度判斷接收完成,共收到 {result.Length} 字節(jié)");
                                    return result;
                                }
                            }
                        }
                    }
                }
                // 超時處理
                isWaitingForResponse = false;
                lock (bufferLock)
                {
                    if (receivedBuffer.Count > 0)
                    {
                        byte[] result = receivedBuffer.ToArray();
                        Console.WriteLine($"幀協(xié)議解析超時,收到 {result.Length} 字節(jié)");
                        return result;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"發(fā)送指令失敗: {ex.Message}");
                isWaitingForResponse = false;
                return null;
            }
        }

        /// <summary>
        /// 方案4: 組合策略 - 最靈活的方案
        /// 同時使用多種判斷條件,任一條件滿足就結(jié)束接收
        /// </summary>
        public byte[] SendQueryWithCombinedStrategy(byte[] command,
            int gapTimeoutMs = 100,
            byte[] endMarker = null,
            int? maxLength = null,
            int maxWaitMs = 3000)
        {
            if (serialPort == null || !serialPort.IsOpen)
            {
                Console.WriteLine("串口未打開");
                return null;
            }
            lock (bufferLock)
            {
                receivedBuffer.Clear();
                isWaitingForResponse = true;
                lastReceiveTime = DateTime.Now;
            }
            try
            {
                serialPort.Write(command, 0, command.Length);
                Console.WriteLine($"已發(fā)送查詢指令: {BitConverter.ToString(command)}");
                DateTime startTime = DateTime.Now;
                while ((DateTime.Now - startTime).TotalMilliseconds < maxWaitMs)
                {
                    Thread.Sleep(10);
                    lock (bufferLock)
                    {
                        if (receivedBuffer.Count == 0) continue;
                        // 條件1: 檢查最大長度限制
                        if (maxLength.HasValue && receivedBuffer.Count >= maxLength.Value)
                        {
                            isWaitingForResponse = false;
                            byte[] result = receivedBuffer.ToArray();
                            Console.WriteLine($"達到最大長度限制,接收完成,共收到 {result.Length} 字節(jié)");
                            return result;
                        }
                        // 條件2: 檢查結(jié)束標記
                        if (endMarker != null && receivedBuffer.Count >= endMarker.Length)
                        {
                            bool foundEndMarker = true;
                            for (int i = 0; i < endMarker.Length; i++)
                            {
                                if (receivedBuffer[receivedBuffer.Count - endMarker.Length + i] != endMarker[i])
                                {
                                    foundEndMarker = false;
                                    break;
                                }
                            }
                            if (foundEndMarker)
                            {
                                isWaitingForResponse = false;
                                byte[] result = receivedBuffer.ToArray();
                                Console.WriteLine($"發(fā)現(xiàn)結(jié)束標記,接收完成,共收到 {result.Length} 字節(jié)");
                                return result;
                            }
                        }
                        // 條件3: 檢查數(shù)據(jù)間隔超時
                        if ((DateTime.Now - lastReceiveTime).TotalMilliseconds > gapTimeoutMs)
                        {
                            isWaitingForResponse = false;
                            byte[] result = receivedBuffer.ToArray();
                            Console.WriteLine($"數(shù)據(jù)間隔超時,接收完成,共收到 {result.Length} 字節(jié)");
                            return result;
                        }
                    }
                }
                // 最大等待時間超時
                isWaitingForResponse = false;
                lock (bufferLock)
                {
                    if (receivedBuffer.Count > 0)
                    {
                        byte[] result = receivedBuffer.ToArray();
                        Console.WriteLine($"最大等待時間超時,收到 {result.Length} 字節(jié)");
                        return result;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"發(fā)送指令失敗: {ex.Message}");
                isWaitingForResponse = false;
                return null;
            }
        }

        /// <summary>
        /// 數(shù)據(jù)接收事件處理
        /// </summary>
        private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (!isWaitingForResponse) return;
            try
            {
                int bytesToRead = serialPort.BytesToRead;
                if (bytesToRead > 0)
                {
                    byte[] buffer = new byte[bytesToRead];
                    int bytesRead = serialPort.Read(buffer, 0, bytesToRead);
                    lock (bufferLock)
                    {
                        receivedBuffer.AddRange(buffer);
                        lastReceiveTime = DateTime.Now; // 更新最后接收時間
                        Console.WriteLine($"收到數(shù)據(jù)包 ({bytesRead} 字節(jié)): {BitConverter.ToString(buffer, 0, bytesRead)}");
                        Console.WriteLine($"當前緩沖區(qū)總計: {receivedBuffer.Count} 字節(jié)");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"數(shù)據(jù)接收處理異常: {ex.Message}");
            }
        }

        /// <summary>
        /// 關(guān)閉串口
        /// </summary>
        public void Close()
        {
            try
            {
                isWaitingForResponse = false;
                if (serialPort != null && serialPort.IsOpen)
                {
                    serialPort.Close();
                    Console.WriteLine("串口已關(guān)閉");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"關(guān)閉串口異常: {ex.Message}");
            }
        }

        public static string[] GetAvailablePorts()
        {
            return SerialPort.GetPortNames();
        }
    }
}
namespace AppFlexSerialPort
{
    internal class Program
    {
        static void Main(string[] args)
        {
            FlexibleSerialPort comm = new FlexibleSerialPort();
            try
            {
                if (comm.InitializePort("COM1", 9600))
                {
                    byte[] queryCommand = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A };
                    Console.WriteLine("=== 方案1: 基于數(shù)據(jù)間隔判斷 ===");
                    byte[] response1 = comm.SendQueryWithGapTimeout(queryCommand, 150, 3000);
                    Thread.Sleep(1000);
                    Console.WriteLine("\n=== 方案2: 基于結(jié)束符判斷 ===");
                    byte[] endMarker = { 0x0D, 0x0A }; // CR LF
                    byte[] response2 = comm.SendQueryWithEndMarker(queryCommand, endMarker);
                    Thread.Sleep(1000);
                    Console.WriteLine("\n=== 方案3: 基于協(xié)議幀結(jié)構(gòu)判斷 ===");
                    byte[] response3 = comm.SendQueryWithFrameProtocol(queryCommand, 0x01, 2, 1);
                    Thread.Sleep(1000);
                    Console.WriteLine("\n=== 方案4: 組合策略 ===");
                    byte[] response4 = comm.SendQueryWithCombinedStrategy(
                        queryCommand,
                        gapTimeoutMs: 100,           // 數(shù)據(jù)間隔100ms
                        endMarker: new byte[] { 0x0A }, // 或者以LF結(jié)尾
                        maxLength: 50,               // 或者最多50字節(jié)
                        maxWaitMs: 3000              // 最多等待3秒
                    );
                }
                Console.WriteLine("按任意鍵退出...");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"程序異常: {ex.Message}");
            }
            finally
            {
                comm.Close();
            }
        }
    }
}

結(jié)果如下: 

性能優(yōu)化與實踐

關(guān)鍵參數(shù)調(diào)優(yōu)

// ? 推薦配置
int gapTimeoutMs = 100;    // 100-200ms適合大多數(shù)設(shè)備
int maxWaitMs = 3000;      // 總超時3秒,避免程序卡死
Thread.Sleep(10);          // 輪詢間隔10ms,平衡CPU占用和響應(yīng)速度

線程安全保障

private readonly object bufferLock = new object();
// 所有緩沖區(qū)操作都要加鎖
lock (bufferLock)
{
    receivedBuffer.Clear();
    receivedBuffer.AddRange(buffer);
    // ... 其他緩沖區(qū)操作
}

常見提醒

1、忘記清空緩沖區(qū):每次查詢前必須 receivedBuffer.Clear()

2、超時時間設(shè)置不當:間隔超時太短會截斷數(shù)據(jù),太長會影響響應(yīng)速度

3、線程安全問題:DataReceived 事件在不同線程中執(zhí)行,必須加鎖保護

4、資源釋放:程序結(jié)束前記得調(diào)用 Close() 方法

適用場景對比

方案適用場景優(yōu)點缺點
間隔超時通用場景簡單可靠需要調(diào)試最佳間隔時間
結(jié)束符判斷文本協(xié)議精確判斷需要明確的結(jié)束符
幀結(jié)構(gòu)判斷二進制協(xié)議最精確需要了解協(xié)議細節(jié)
組合策略復(fù)雜場景最靈活代碼稍復(fù)雜

總結(jié)

1、選擇合適的策略:對于90%的場景,數(shù)據(jù)間隔超時判斷就足夠了

2、參數(shù)調(diào)優(yōu)很重要:100-200ms 的間隔超時是經(jīng)驗值,需要根據(jù)實際設(shè)備調(diào)整

3、組合策略是王道:當單一策略無法滿足需求時,組合策略提供了最大的靈活性

通過本文介紹的四種策略,開發(fā)者可以根據(jù)具體通信協(xié)議靈活選擇最適合的接收方式,徹底告別"分包接收"帶來的困擾。

到此這篇關(guān)于C#實現(xiàn)串口通信的四種靈活策略和避坑指南的文章就介紹到這了,更多相關(guān)C#串口通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

拉萨市| 鲁山县| 兴隆县| 清涧县| 乐清市| 宕昌县| 宁海县| 绍兴市| 大宁县| 朝阳市| 广平县| 黎城县| 西贡区| 陇川县| 独山县| 从化市| 肥西县| 汝城县| 南开区| 定兴县| 二手房| 元阳县| 孟连| 尚志市| 万山特区| 昌都县| 颍上县| 林芝县| 遂平县| 保亭| 五指山市| 邹城市| 庆安县| 罗定市| 桃园县| 南汇区| 若尔盖县| 安溪县| 旅游| 丽水市| 林州市|