You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:54:32