Boost Asio串口async_read无数据时提前完成(bytes_read=0且错误码为成功)的问题咨询
Boost Asio串口async_read无数据时提前完成(bytes_read=0且错误码为成功)的问题咨询
我在Windows系统上封装了一个boost::asio::serial_port的类,用来对传入的缓冲区发起异步读取操作。
多数情况下,在调用async_read之前队列里已有数据时,这个功能都能正常工作(我还尝试用ClearCommError函数来轮询数据状态)。
但问题来了:当队列里没有数据时,我的异步调用会直接完成,返回bytes_read = 0,而且error_code是success(成功)。
我做过调试,如果在调用后等待数据到来,是能读到预期的所有字节的。
这种情况有没有官方文档说明的成因?还是说这可能是个bug?
下面是出问题的函数代码:
bool stream_channel_serial_device::async_read_bytes( std::span<uint8_t> buffer, completion_handler&& handler ) { // 调用时缓冲区大小为536字节 boost::asio::async_read( serial_port_, boost::asio::buffer(buffer), // 缓冲区大小是536字节 [this, handler = std::move(handler)] (boost::system::error_code const& ec, std::size_t bytes_read) { if (ec) { // 这里不会触发(也就是ec是成功状态),但bytes_read是0! log_error("Error reading data package: " + ec.message()); } handler(rx_status{ec, bytes_read}); } ); return true; }
补充说明:
- 串口是类的成员变量:
boost::asio::serial_port serial_port_; - 我用的是虚拟串口,但它没有引发过其他问题(理论上应该完全模拟真实COM口的行为)
编辑1:
我添加了使用Boost Asio handler tracking功能的输出结果,里面清晰显示handler 432提前进入,读取了0字节且无错误码:
@asio|1732123199.067050|<428| @asio|1732123199.067050|>429|ec=system:0,bytes_transferred=536 @asio|1732123199.071049|429^430|in 'async_read' (.\build\default\vcpkg_installed\x64-windows\include\bo:373) @asio|1732123199.071049|429*430|handle@00000204B3E829C0.async_read_some @asio|1732123199.098571|<429| @asio|1732123199.098571|>430|ec=system:0,bytes_transferred=536 @asio|1732123199.101569|430^431|in 'async_read' (.\build\default\vcpkg_installed\x64-windows\include\bo:373) @asio|1732123199.101569|430*431|handle@00000204B3E829C0.async_read_some @asio|1732123199.130571|<430| @asio|1732123199.130571|>431|ec=system:0,bytes_transferred=536 @asio|1732123199.131573|431|handle@00000204B3E829C0.close @asio|1732123199.139613|431^432|in 'async_read' (.\build\default\vcpkg_installed\x64-windows\include\bo:373) @asio|1732123199.139613|431*432|handle@00000204B3E829C0.async_read_some @asio|1732123199.140618|<431| @asio|1732123199.161532|>432|ec=system:0,bytes_transferred=0
编辑2:
这个问题似乎只有在先向串口写入过数据后才会出现。如果我不先写数据,异步读取会正常等待数据到来。
编辑3:
如果我通过Windows的native_handle()给串口设置超时,这个问题就不会出现,但这样一来我的代码就依赖于特定的超时时间,而且失去了跨平台性。
备注:内容来源于stack exchange,提问作者SupAl
相关产品推荐
相关产品推荐

