Reading a Serial Port Asynchronously Boost

寵の児 提交于 2019-12-21 20:44:21

问题


I am trying to read several bytes asynchronously from a serial port. Currently the code I am using (source is How do I perform a nonblocking read using asio?), only allows me to read 1 byte and then it exits. How do I get it so that the code keeps reading until there is no more incoming data in the serial port? Thanks :)

    void foo()
{
    boost::asio::io_service io_svc;
    boost::asio::serial_port ser_port(io_svc, "/dev/ttyS0");
    boost::asio::deadline_timer timeout(io_svc);
    unsigned char my_buffer[2];
    bool data_available = false;

    ser_port.async_read_some(boost::asio::buffer(my_buffer),
            boost::bind(&read_callback, boost::ref(data_available),
                    boost::ref(timeout),boost::asio::placeholders::error(),
                    boost::asio::placeholders::bytes_transferred()));
    timeout.expires_from_now(boost::posix_time::seconds(30));
    timeout.async_wait(boost::bind(&wait_callback, boost::ref(ser_port),boost::asio::placeholders::error()));

    io_svc.run();

    io_svc.

    if(!data_available)
    {
        ser_port.close();
        cout << "ser_port was closed";
    }

}

void read_callback(bool& data_available, boost::asio::deadline_timer& timeout, const boost::system::error_code& error, std::size_t bytes_transferred)
{
    if (error || !bytes_transferred)
    {
        // No data was read!
        data_available = false;
        return;
    }

    timeout.cancel();
    data_available = true;
}

void wait_callback(boost::asio::serial_port& ser_port, const boost::system::error_code& error)
{
    if (error)
    {
        // Data was read and this timeout was cancelled

        return;
    }

    ser_port.cancel();
}

回答1:


In your read_callback you cancel your timer and do not start a new read.
So what do you expect ASIO to do. You just canceled all handlers and like the documentation states, the run method will return when no handlers are left.

So if you want to have more data than just the one byte you receive you can do two things:
First just issue another call to asio to read more from the port.

void read_callback(bool& data_available, boost::asio::deadline_timer& timeout, const  boost::system::error_code& error, std::size_t bytes_transferred)
{
    if (error || !bytes_transferred)
    {
        // No data was read!
        data_available = false;
        return;
    }
    // do something with the data you just read
    ser_port.async_read_some(boost::asio::buffer(my_buffer),
        boost::bind(&read_callback, boost::ref(data_available),
                boost::ref(timeout),boost::asio::placeholders::error(),
                boost::asio::placeholders::bytes_transferred()));
    //restart your timer
    data_available = true;
}

or you can add use transfer_at_least to get at least the amount of data you need.



来源:https://stackoverflow.com/questions/17551617/reading-a-serial-port-asynchronously-boost

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!