C# 串行端口上的读取不';I don’我不能给我预期的结果

C# 串行端口上的读取不';I don’我不能给我预期的结果,c#,serial-port,C#,Serial Port,我试图读取串行端口上的一些数据,但在监视器软件(如232分析仪)和我的程序之间没有相同的结果 以下是232分析仪的读数: 001 003 001 102 000 004 165 234 001 003 006 144 000 008 068 169 001 003 005 000 000 042 196 217 001 003 001 096 000 042 197 247 001 003 001 096 000 042 197 247 001 003 014 000 000 042

我试图读取串行端口上的一些数据,但在监视器软件(如232分析仪)和我的程序之间没有相同的结果

以下是232分析仪的读数:

001 003 001 102 000 004 165 234 
001 003 006 144 000 008 068 169 
001 003 005 000 000 042 196 217 
001 003 001 096 000 042 197 247 
001 003 001 096 000 042 197 247 
001 003 014 000 000 042 198 253 
下面是我从SerialPort读到的内容:

 001
 003 001 102 000 004 165 234
 001
 003 006 144 000 008 068 169
 001
 003 005 000
 000 042 196 217
 001
 003 001 096 000 042 197 247
 001
 003
 001 096 000 042 197 247
 001
 003 014 000 000 042 198 253
我所有的帧都被“截断”,我不知道为什么。 串行端口在两个程序的
9600,n,8,1
中配置

如何修复此问题并获得与232 analyzer中相同的帧

附言:

我得到这样的帧(ReadTimeout设置为200ms):


编辑 当执行
线程时,睡眠(10)阅读前,我得到:

 001
 003 001 102 000 004 165 234
 001
 003 006 144 000 008 068 169
 001
 003 005 000 000 042
 196 217
 001
 003 001 096 000 042 197 247
 001
 003 001 096 000
 042 197 247
 001
 003 014 000 000 042 198 253

IIRC只有在没有数据等待的情况下,才会执行ReadTimeout,因此,只要第一个字节已经在FIFO缓冲区中,sp.Read()就会立即返回,给出任何可用的数据

串行端口的行为是一个流,而不是一系列帧——任何帧都必须来自应用程序

收到反馈后更新:由于框架来自应用程序,因此您必须知道框架大小。这可能被编码为帧头的一部分,在这种情况下,逐字节读取可能是最好的解决方案。如果有固定长度的帧(示例中为8字节),则可以使用

while(true)
{
    byte[] frame = new byte[8];
    int read = 0;
    while (read<8)
    {
        sp.Read(frame, read, 8-read);
    }
    // ...
}
while(true)
{
字节[]帧=新字节[8];
int read=0;

而(readIIRC)只有在没有数据等待的情况下才会执行ReadTimeout,因此,只要第一个字节已经在FIFO缓冲区中,sp.read()就会立即返回,给出任何可用的数据

串行端口的行为是一个流,而不是一系列帧——任何帧都必须来自应用程序

收到反馈后更新:由于帧来自应用程序,您必须知道帧大小。这可能作为帧头的一部分进行编码,在这种情况下,逐字节读取可能是最佳解决方案。如果有固定长度的帧(示例中为8字节),您可以使用

while(true)
{
    byte[] frame = new byte[8];
    int read = 0;
    while (read<8)
    {
        sp.Read(frame, read, 8-read);
    }
    // ...
}
while(true)
{
字节[]帧=新字节[8];
int read=0;

而(read串行端口是完全不受限制的,因此每当您读取时,您都会读取可用的数据。这可能是1字节、10字节或1024字节。稍等一会儿,您将拥有更多数据,尽管数据大小完全不可预测,除非您一次只读取一个字节


“监视器”软件可能只是简单地将其格式化为漂亮的数据块。

串行端口完全不受限制,因此每当您读取时,您都会读取可用的数据。这可能是1字节、10字节或1024字节。稍等一会儿,您将拥有更多的数据,尽管数据的大小完全不可预测,除非您一次只读取一个字节


“监视器”软件可能只是简单地将其格式化为好的块。

是的,我知道,但我不明白的是,为什么232 analyzer会给我预期的结果(结果I除外)我的程序不是。大多数RS232分析器使用空格或换行符来表示流中的暂停。当通信伙伴发送帧数据时,这将导致不活动时间转换为换行符。仅为了诊断,请在sp.Read()之前尝试线程。Sleep(10)-一个8字节的帧应该比这个小一些。我编辑了我的问题,结果添加了
线程。Sleep(10);
。我对新行没问题,但我读的流不是“新行”…如果你的帧是固定长度的,请使用更新我的答案。通过“翻译成新行”我的意思是由分析器翻译,而不是应用程序。是的,我知道,但我不明白的是,为什么232分析器会给我预期的结果(结果I除外)我的程序不是。大多数RS232分析器使用空格或换行符来表示流中的暂停。当通信伙伴发送帧数据时,这将导致不活动时间转换为换行符。仅为了诊断,请在sp.Read()之前尝试线程。Sleep(10)-一个8字节的帧所需的时间应该比这个小一些。我编辑了我的问题,结果添加了
线程。Sleep(10);
。我对新行没问题,但我读的流不是“新行”…如果你的帧是固定长度的,请使用更新我的答案。我说的“翻译成新行”是指由分析器翻译,而不是应用程序翻译。[在你编辑之后]我不会依赖睡眠(10)睡眠10毫秒,等待你的字节数就确定了。你有一个缓冲数据的硬件串行端口,一个可能进行缓冲的操作系统,然后你的程序同时运行。永远不要依赖操作系统计时从端口获得确定的字节数。如果它还没有准备好重新启动广告,它不会为你提供数据。这个Thread.Sleep(10)来自我的评论,前缀是“Just for Diagnostics”-它从来不是[编辑后]的解决方案,我不会依赖睡眠(10)睡眠10毫秒,等待你的字节数就确定了。你有一个缓冲数据的硬件串行端口,一个可能进行缓冲的操作系统,然后你的程序同时运行。永远不要依赖操作系统计时从端口获得确定的字节数。如果它还没有准备好重新启动广告,它不会有数据给你。这个Thread.Sleep(10)来自我的评论,前缀是“Just for diagnosis”-它从来就不是一个解决方案