我有一个具有二进制输出的串行设备,我使用以下内容捕获数据。
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int count = sp.BytesToRead;
byte[] data = new byte[count];
sp.Read(data, 0, data.Length);
file.WriteLine(BitConverter.ToString(data));
}
数据来了,看起来像这样......
06-14-F2-A1-64-2D-62-00-1A-31-00-06-14-F3-84-62-59-01-00-1A-31-00-06-14-F3-85-56-52-55-31
1A-31-00-06-14-F4-18-04-2E-62-00-1A-31-00-06-14-F4-E3-27-5B-01-00-1A-31-00-06-14-F4-E4-1C-51-55-31
1A-31-00-06-14-F5-71-4C-59-71-20-1A-31-00-06-14-F5-8E-A5-2E-62-00-1A-31-00-06-14-F5-F4-47-56-55-31-1A-31-00-06-14-F6-10-1A-1A-31-52-24-1A-31-00-06-14-F6-3D-40-19-70-00-1A-31-00-06-14-F6-3E-9C-4C-55-31-1A-33-00-06-14-F6-F6-11-3D-A0-00-17-B0-C8-4E-42-70-AA-00-00-59-51-1E-1A-31-00-06-14-F7-05-4A-2E-62-00-1A-31-00-06-14-F7-83-5C-56-55-31-1A-31-00-06-14-F7-99-04-5A-01-00-1A-31-00-06-14-F7-99-F8-51-55-31-1A-31-00-06-14-F8-7B-EA-2E-62-00-1A-31-00-06-14-F9-00-CE-56-01-00-1A-31-00-06-14-F9-0E-DF-51-55-31-1A-31-00-06-14-F9-F2-8B-2B-62-00-1A-31-00-06-14-FA-15-1F-1D-05-30-1A-31-00-06-14-FA-62-4D-59-01-00-1A-31-00-06-14-FA-63-41-55-55-31-1A-31-00-06-14-FA-6F-6E-1D-67-67-1A-31-00-06-14-FA-EC-50-2E-72-00-1A-31-00-06-14-FB-22-96-38-62-00-1A-31-00-06-14-FB-3B-7A-40-20-43-1A-31-00-06-14-FB-69-2E-2B-62-00-1A-31-00-06-14-FC-62-F1-2D-72-00-1A-31-00-06-14-FC-DF-D1-2E-62-00-1A-31-00-06
十六进制在这里不是问题,因为我可以解码,但我正在寻找的语句以 1A-31 开头,然后是一个设定的字节数。正如您所看到的,在这种情况下,串行流开始中间流,因此不是完整的语句。
如何查找此标记,丢弃开头然后开始处理。还要记住,这会发生多次,因为readBuffer在某些时候会截断流,我需要再将它重新组合在一起吗?
答案 0 :(得分:3)
你快到了。您的问题是您流式传输的数据是块状的,与语句的开始和结束位置不一致。我将假设1A-31找到一个语句的 end ,它标识下一个语句的开头。如果不是这样,请相应地重新解释这个答案。
现在,您将无法对示例中包含半个语句的第一批数据执行任何操作。所以,让我们先假设您获得的第一个数据块确实以1A-31开头。
现在有两种选择:
StatementReceived
事件并将其发送到那里,或类似的东西)。重复此练习,直到块完全处理完毕。port_DataReceived
调用。如果是第二种选择,您知道下一个port_DataReceived
的数据不会以1A-31开头(因为临时缓冲区非空)。但是,您可以扫描到它的末尾(直到下一个1A-31),将临时缓冲区(存储在前一个port_DataReceived
调用中)添加到它,然后引发StatementReceived
并清除临时缓冲区
使用类似的方法,您还可以处理需要发送超过2个数据块的语句;每次没有遇到1A-31时,将接收的数据附加到临时缓冲区,直到语句完成。
最后,如果您在启动时读取的第一个字节不是以1A-31开头的,那么您只需要丢弃它们。用半个声明做不了什么。