Visual c++ 如何设置固定字节数据包之间的读取超时? 我在Visual C++ 2008中开发了一个应用程序,它应该通过串行接口读取从硬件设备接收的一些数据。数据以每50毫秒45字节的数据包形式发送。我正在使用WIN32 API提供的函数来执行所有必要的任务,如打开和关闭端口

Visual c++ 如何设置固定字节数据包之间的读取超时? 我在Visual C++ 2008中开发了一个应用程序,它应该通过串行接口读取从硬件设备接收的一些数据。数据以每50毫秒45字节的数据包形式发送。我正在使用WIN32 API提供的函数来执行所有必要的任务,如打开和关闭端口,visual-c++,serial-port,Visual C++,Serial Port,这是我的 在这篇文章中,作者提到了设置超时等待数据的过程 COMMTIMEOUTS timeouts = { 0 }; timeouts.ReadIntervalTimeout = 50; // in milliseconds timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds timeouts.ReadTotalTimeoutMultiplier = 10; // in milliseconds time

这是我的

在这篇文章中,作者提到了设置超时等待数据的过程

COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout         = 50; // in milliseconds
timeouts.ReadTotalTimeoutConstant    = 50; // in milliseconds
timeouts.ReadTotalTimeoutMultiplier  = 10; // in milliseconds
timeouts.WriteTotalTimeoutConstant   = 50; // in milliseconds
timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
COMMTIMEOUTS结构的第一个成员是两个连续字节之间的等待时间。这对我来说应该是0,因为我一次收到45个字节,然后在等待下一个数据包时必须是50毫秒

设置DCB结构时,将字节大小设置为8*45位,然后将ReadIntervalTimeout设置为50毫秒是否有效

编辑:不会的。我刚刚读到字节大小的定义是在4到8之间。我还有别的办法吗

我还可以用这些超时设置事件处理程序吗?我希望能够保持应用程序运行,而它只在检测到数据时读取。但是,如果启动硬件设备已经发送了45个字节中的20个,则应用程序可能会将字节21视为第一个字节。这种恐惧是没有根据的吗

编辑2:我已将我的读取功能修改为以下内容,以便检查适当的标题

void CGCUGUIDlg::fnRead()
{
    char TempChar; //Temporary character used for reading
    char SerialBuffer[45];//Buffer for storing Rxed Data
    DWORD NoBytesRead;
    int i = 0;
    do
    {
        ReadFile( m_hComm,           //Handle of the Serial port
             &TempChar,       //Temporary character
             sizeof(TempChar),//Size of TempChar
             &NoBytesRead,    //Number of bytes read
             NULL);

        if(TempChar == 0x10||0x80)
        {SerialBuffer[i] = TempChar;// Store Tempchar into buffer
        i++;}
    }

    while (NoBytesRead > 0);
}

在你的接收应用程序中,你需要实现你的协议——你的代码需要以不同步的方式开始,这意味着在你的情况下,它会寻找一个页眉和页脚,它们之间的间隔是正确的字节数,然后丢弃数据,直到找到为止。当找到它们时,协议被同步,数据包被发送以供使用,并且协议始终保持检查页眉/页脚-如果找到,数据将作为数据包接受,如果没有找到,状态将恢复为未同步。寻找数据包的代码应该积累数据,一旦同步,必须只消耗数据包的长度,即如果收到46个字节,则消耗45个字节,然后继续向剩余的1个字节添加数据,直到达到45个或更多,并且不要丢弃更多的数据包。当你开始工作时,你就不需要担心数据包之间的间隙了。通常的方法是,您维护一个缓冲区,将接收到的字节添加到该缓冲区中,并从中消耗数据,将未消耗的数据作为下一个数据包添加到该缓冲区中-这样您就不需要代码担心数据包之间的超时或意外的处理延迟等问题。

您的担心听起来并不是毫无根据的。除了计时之外,是否有其他方法来区分数据包的结束/开始,这是一件很难区分的事情?若并没有,你们可以添加一些独特的框架,让你们的接收应用程序和包边界同步。它有一个预定义的页眉和页脚。页眉为0x10或0x80,页脚为0x1F或0x8F。但是我该如何检查这个呢?还有,如何设置50毫秒的间隔?编辑:我将ReadIntervalTimeout设置为50毫秒,其余设置为零。这是否意味着应用程序将在第一个字节之前等待任意时间,然后填充我将设置为45的缓冲区,然后等待50毫秒?这无法正常工作。超时由驱动程序测量,它与程序的执行完全不同步。您总是需要一个协议来将字节分组到消息中。简单的方法是一个唯一的最终字节'\n',通常是消息开头的一个字节,指示跟随的数量。确保接收器和发射器总是同步的,因此接收器在打开端口后不尝试在中间读取消息。通常需要一个唯一的开始字节。@HansPassant那么,我的编辑读取函数是否会这样做,因为我已经设置了检查唯一页眉的条件?因此,如果我确信页眉和页脚将相隔43字节,我是否可以减少同步条件,只查找页眉?我已经在上面添加了我修改过的读取函数。你的头字节可以出现在这43个字节中吗?如果是这样,您就更需要确保您实际检测到了真正的标题。对我来说,如果你得到了页脚无论如何你可以使用它。您必须在头后组装以下43个字节,因此您可以等待第44个字节并检查它。您每次读取一个字节的传入数据,这似乎效率不高,但可能会在以后修复,我看不出当I>0时,您的代码如何处理头后的字节,我看不出当I==43并且接收到另一个字符时,您的代码是如何检查页脚的,然后才将累积的消息发送出去进行处理。我假设正在工作。这可能是一种很好的防御方法,可以确保您记录同步和同步丢失的发生。我假设正在工作。哦,绝对是的。我需要 同时学习和编码。我还打算将I++放在if循环之外。还有,标题后面的字节是什么意思?如果满足if子句,它不就被添加到缓冲区吗?我正在重新编写代码以包括页脚条件。