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

boost::asio串口异步接收数据失败,同步接收正常问题求助

问题分析与解决

核心问题:未启动io_context事件循环

Boost.Asio的所有异步操作都依赖io_context调度执行回调函数。你的代码仅发起了异步读操作,但从未启动io_context的事件循环,导致异步回调永远不会触发。

修复方案

必须调用io_context的run()、run_one()或poll()方法处理事件,以下是两种常用实现:

1. 主线程启动事件循环(推荐)

修改main.cpp:

SerialPort sp;

int main()
{
    sp.open_port("COM11");
    sp.write_sync("Testing123");
    sp.read_async();

    // 启动io_context事件循环,阻塞到所有异步操作完成或被停止
    sp.get_io_context().run(); 
    return 0;
}

同时在SerialPort.hpp中添加获取io_context的公开接口:

public:
    boost::asio::io_context& get_io_context() { return io; }

2. 独立线程运行事件循环

若不想阻塞主线程,可创建专门线程运行io_context:
在SerialPort.hpp中添加线程成员:

private:
    std::thread io_thread;

修改open_port方法启动线程:

bool SerialPort::open_port(void)
{
    try
    {
        this->port.open(this->port_name);
        // 启动io_context线程
        io_thread = std::thread([this](){ io.run(); });
        return true;
    }
    catch (const std::exception& ex)
    {
        PLOG_FATAL << ex.what();
    }
    return false;
}

在析构函数中停止并等待线程:

SerialPort::~SerialPort()
{
    io.stop();
    if (io_thread.joinable())
        io_thread.join();
}

其他潜在问题修复

  • 持续接收需求:当前read_handler仅处理一次数据,若要持续接收,需在回调末尾再次发起异步读:
void SerialPort::read_handler(const boost::system::error_code& error, std::size_t bytes_transferred)
{
    if (!error)
    {
        std::string received_data_buffer;
        std::transform(this->read_buffer.begin(), this->read_buffer.begin() + bytes_transferred,
            std::back_inserter(received_data_buffer), [](std::byte character) {
                return static_cast<char>(character);
            });
        PLOG_INFO << "In Read Buffer : " << received_data_buffer;

        // 再次发起异步读,保持持续接收
        this->port.async_read_some(boost::asio::buffer(this->read_buffer.data(), this->read_buffer.size()),
            boost::bind(&SerialPort::read_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
    }
    else
    {
        PLOG_ERROR << "Read error: " << error.message();
    }
}
  • 串口参数校验:确保异步操作前已正确配置波特率、奇偶校验等串口参数(同步能工作不代表参数完全适配异步场景),示例:
port.set_option(boost::asio::serial_port_base::baud_rate(9600));
port.set_option(boost::asio::serial_port_base::character_size(8));
port.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));
port.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none));

内容的提问来源于stack exchange,提问作者Dark Sorrow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:21:17