我正在使用Boost ASIO(版本1.64.0)使用超时从Windows上的串行端口执行异步读取。
我这样做是通过配置一个超时处理程序和一个读处理程序,然后像这样设置它们:
port->async_read_some(buffer, readHandler);
timer.expires_from_now(timeoutMilisec);
timer.async_wait(timeoutHandler);
在超时处理程序中,如果没有错误,我会调用port->cancel()
我遇到的问题是,如果此超时事件恰好在数据到达串行端口时发生,则该数据将丢失。在刚刚取消的readHandler中没有拾取它(它返回错误)。在随后的async_read_some
调用中未将其接收。有没有办法执行异步串口读取,没有数据丢失的风险? port->cancel()
不会阻止数据丢失吗?
注意:我通过将超时时间设置为消息间隔的大约1/2来验证问题是时间。它并不总是会发生,但大约有10条消息丢失了。如果我将超时时间更改为始终长于消息间隔,我没有看到问题(尽管如果我不幸的话,我认为可能发生在第一条消息上)。
编辑:我从不取消async_read_some()
操作,解决了这个问题。相反,我将读取的数据收集到我的应用程序控制的缓冲区中(我使用该中间缓冲区来确定请求是否超时)。我仍然认为Boost ASIO在port->cancel()
可能丢失数据时做错了什么,但如果有人知道细节,我很乐意听到解释。也许有一些关于Windows串口API的东西让这变得不可能。在我之前使用Linux的经历中,我已经能够在串口上轻松选择()而不消耗数据。