关于cnComm串口类库的问题解决方案,就是很多人说的只读几个字节的问题

本文介绍了一种解决异步通讯模式下Read函数仅读取部分字节问题的方法,通过缓存和标志位检测确保完整接收数据包。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我收到许多来信,都问我为什么Read函数只读几个字节 ,我都快被问晕了。

当然这不是我的库的问题,这是很基本的通讯问题,因为通讯中传输需要时间,当你选择异步模式时你应该注意,这时候Read函数是非阻塞状态,意味着Read函数会迅速扫描缓冲区,把缓冲区里的字节读出来,这时候缓冲区里有多少字节就读多少字节,字节的多少取决于通讯速度与你计算机速度,你通讯越快,读得越多,计算机越快读得越少,这个容易理解吧。

所以这个不是一个问题,不需要执著于它,但是你如何实现应用?

我告诉你一个方案:

比如你有一个业务,一个仪表设备不停的发送数据给计算机,格式为"/x2  /xXX /xXX ............ /x3"

其中'/x2'是开始标志, '/x3'是结束标志, '/xXX'是数据,长度不定,也许1k 也学2k,假设数据不会出现标识位,那么程序应该这么写:

class MyComm : public cnComm
{
 virtual void OnReceive()
 {
  static char buffer[8192];//临时缓冲区
  static int buffer_index = 0;//数据索引,指向需要插入数据的点

  buffer_index += Read(buffer+buffer_index, 8192-buffer_index);
  
  char *find_ptr = std::find(buffer, buffer+buffer_index, '/x2');//查找开始标志
  if(find_ptr != buffer+buffer_index)//找到开始标志
  {
   char * find_end_ptr = std::find(find_ptr, buffer+buffer_index, '/x3');//查找结束标志
   if(find_end_ptr != buffer+buffer_index)//找到结束标志
   {
    char* data_buffer = new char[find_end_ptr-find_ptr+1];
    std::copy(data_buffer, find_ptr, find_end_ptr+1);//拷贝数据
    PostMessage(_hNotifyWnd, WM_DATA_COME, (WPARAM)data_buffer, 0);
    //发送数据到主窗口去处理
    std::copy(find_end_ptr+1, buffer+buffer_index, buffer);//删除
    buffer_index = buffer+buffer_index-find_end_ptr-1;//修正插入数据的点数据索引
   }
   else
   {
    if(buffer_index == 8192)
    {
     //说明缓冲区溢出, 你要报错!
    }
   }
  }
  else ////找不到标志
  {
   //说明通讯中存在垃圾数据,要清除它,留出缓冲区
   buffer_index = 0;//注这里标识位只有一个字节所以全部删除
   //如果标识位>1个字节, 比如开始标志为"/x2/xa/xb"
   //程序就要这么写:
   //std::copy(buffer+buffer_index-2, buffer+buffer_index, buffer);
   //buffer_index = 2;
  }
 }
public:

};

 

看明白,里面有用到C++的标准库,代码只是示意,没有测试,但是逻辑和意识是正确的。

我看到好多人认为这个问题指责我的库,希望以后不会有,还有人建议用国外的,呵呵,没关系,不用就不用,我这也是方便又需要的人,对我自己来说,并没有太多的必要,谢谢!

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值