c++ - 如何使用 COMMTIMEOUTS 等待直到字节可用但读取了一个以上的字节?

标签 c++ winapi serial-port communication

我有一个 C++ 串口类,它有一个非阻塞模式和一个用于读取操作的阻塞模式。对于阻塞模式:

COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 0;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
SetCommTimeouts(m_hFile,&cto)

对于非阻塞模式:

COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = MAXDWORD;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
SetCommTimeouts(m_hFile,&cto)

我想添加另一种等待任意数量的字节并读取它们的模式。

来自 MSDN COMMTIMEOUTS structure :

如果应用程序将 ReadIntervalTimeoutReadTotalTimeoutMultiplier 设置为 MAXDWORD 并将 ReadTotalTimeoutConstant 设置为大于零的值并且小于 MAXDWORD,调用 ReadFile 函数时会出现以下情况之一:

  • 如果输入缓冲区中有任何字节,ReadFile 会立即返回缓冲区中的字节。
  • 如果输入缓冲区中没有字节,ReadFile 等待直到 字节到达然后立即返回。
  • 如果在指定的时间内没有字节到达 ReadTotalTimeoutConstant,ReadFile 超时。

这看起来像这样的代码:

COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 100;
cto.ReadTotalTimeoutConstant = MAXDWORD;
cto.ReadTotalTimeoutMultiplier = MAXDWORD;
SetCommTimeouts(m_hFile,&cto)

但这会在第一个字节处立即返回。这是一个问题,因为我正在循环读取端口并且字节的处理速度如此之快以至于下次我读取端口时,只有另一个字节可用。最终结果是我在一个循环中一次读取一个字节,并使用 100% 的核心运行该线程。

我想像 MSDN 文档中那样使用 cto.ReadIntervalTimeout,但仍然要等到至少有一个字节可用。有人有想法吗?

谢谢。

最佳答案

您想要的行为将来自:

cto.ReadIntervalTimeout = 10;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;

它会阻塞任意长的第一个字节(根据文档,通过将后两个字段设置为零来禁用总超时),然后只要数据流入就读取缓冲区大小。如果有 10 毫秒的间隔在数据中,它将返回到目前为止收到的内容。

关于c++ - 如何使用 COMMTIMEOUTS 等待直到字节可用但读取了一个以上的字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10390151/

相关文章:

c++ - 在循环内使用时,使用 getline 将单词存储在 char 数组中不起作用?

c++ - 同时持有两个互斥锁

c++ - 调整我简单的 OpenGL/GLUT 窗口的大小会产生奇怪的线条

c++ - 使用 CB_SETCURSEL 时如何发送 CBN_SELCHANGE 消息?

c++ - 如何使用 VirtualDesktopManager 界面?

c++ - 将工具提示添加到 ComboBoxEx 失败

android - Samsung Galaxy Y (Android 2.3) 串口短信命令Ctrl+Z错误

c++ - Qtsql 中的参数计数不匹配

c++ - 如果找不到任何内容,Serial.find 是否会清除缓冲区

linux - 更改运行 Angstrom Linux 的 BeagleBone UART0 的波特率