You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效接收不定长度的串口数据?(.NET Framework 4.6)

不定长度串口数据接收优化方案

现有实现及问题

我在while循环中实现了一种串口数据消息接收方法,每条消息长度在100-2048字节之间,多数约为1000字节。现有实现代码如下:

public int RecvSerialData(ref byte[] respBuf, int delay)
{
    var recvBuf = new byte[2048];
    var count = m_serial.BytesToRead;
    if (count > 0)
    {
        var sw = new Stopwatch();
        sw.Restart();
        while (sw.ElapsedMilliseconds < delay)
        {
        }

        count = m_serial.BytesToRead;
        m_serial.Read(recvBuf, 0, count);
        
        // Do something with respBuf
        return count;
    }
    return -1;
}

当前核心问题是通信协议未包含消息长度字段,无法获知每条消息的准确长度。因此传入延迟参数时陷入两难:延迟过长会浪费大量时间,过短则可能导致消息接收不完整。

补充说明

  • 客户端需等待我方回复前一条消息后才会发送下一条,因此即使设置很长的延迟,也不会接收到下一条消息。
  • 实际测试显示,设置30ms延迟时,接收所有消息耗时超65秒,但能完整接收;设置5ms延迟时,耗时不足20秒,但部分消息接收不完整引发问题。
  • 项目基于.NET Framework 4.6的WinForm应用。

协议格式

  • Host(1字节,固定为0x02)
  • Step(1字节,当前固定为0x35)
  • InfoA(1字节)
  • InfoB(2字节)
  • ACK/NAK(1字节)
  • Error Code(4字节)
  • InfoC(2字节)
  • Body(0-2000字节)

Info区域用于传输客户端信息,类似Host和Step,无长度或CRC字段。

优化后的实现方案

我找到了一个较好的方案,虽不完美但足以满足需求,代码如下:

public int RecvSerialData(ref byte[] respBuf)
{
    var recvBuf = new byte[2048];
    var count = m_serial.BytesToRead;
    if (count > 0)
    {
        var offset = 0;
        m_serial.Read(recvBuf, offset, count);      
        offset += count;
        while(true)
        {
             count = m_serial.BytesToRead;
             if(count == 0)
             {
                 break;
             }
             m_serial.Read(recvBuf, offset, count);
             offset += count;
             Thread.Sleep(5);
        }

        // Do something with respBuf
        return offset;
    }
    return -1;
}

该方案对多数数据仅需休眠5ms或10ms,效果符合预期。

内容的提问来源于stack exchange,提问作者WangDaChui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:59:54