简体   繁体   中英

asynchronous read write with device file

I am writing some binary data to a device fie like /dev/itun.

void ahaConnector::asyncWriteData(vector<uint8_t> packedMessage) {

    cout<<"\n async write data packed message";
    deviceStreamDescriptor.assign(device);
    boost::asio::write (
                       deviceStreamDescriptor,
                       boost::asio::buffer(packedMessage)
                       );


    readbuffer.resize(1024);
    deviceStreamDescriptor.async_read_some(boost::asio::buffer(readbuffer),
                                boost::bind(&ahaConnector::readHeader, this,
                                boost::asio::placeholders::error(),
                                boost::asio::placeholders::bytes_transferred()
                                ));
    io_service.run();

}

void ahaConnector::readHeader(const boost::system::error_code &ec, std::size_t bytes_transferred) {


    if(!ec) {

        std::cout<<"\n Bytes transfereed :"<<bytes_transferred<<" "<<readbuffer.size();


        deviceStreamDescriptor.async_read_some(boost::asio::buffer(readbuffer),
                                        boost::bind(&ahaConnector::readHeader, this,
                                        boost::asio::placeholders::error(),
                                        boost::asio::placeholders::bytes_transferred()
                                        ));

        Callbacks callbacks;
        callbacks.OnReceivingPackedMessage();
        io_service.run();

    }
    else {

        cout<<"\n System Error Code "<<ec;
    }

}

The callback function readhandler is getting executed successfully, however I am not able to transfer the control from my Callback function to another class.

Is something wrong from the design perspective. I need to handle the message received from the callback function for further logic. Should I use another thread here ?

The answer depends on exactly what are the properties of the device. Check the documentation for the device driver you're trying to use. If the device supports non-blocking I/O, open the device with O_NONBLOCK , and use poll() to wait for device to be available for reading or writing.

If the device does not support non-blocking I/O, the only viable option would be to use a separate thread to read and/or write to the device, and use the background thread to construct facade that pretends and behaves like a non/blocking data source and sink.

Looking at this code you might just want to replace the read(device,...) by boost Asio's support for Posix streams:

#include <boost/asio.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/function.hpp>
#include <iostream>

static int device = 0;

using namespace boost;

int main() {
    boost::asio::io_service io_svc;
    boost::asio::posix::stream_descriptor iodevice(io_svc, device);

    char buffer[1024];
    function<void(system::error_code const&, size_t)> callback;
    callback = [&](boost::system::error_code const& ec, size_t bytes_transferred) {
            if (ec)
            {
                std::cout << "Error '" << ec.message() << "' during asynchronous operation\n";
            }
            else
            {
                std::cout << "Read exactly " << bytes_transferred << " bytes\n";
                std::cout << "Data: '"; 
                std::cout.write(buffer, bytes_transferred);  
                std::cout << "'\n";

                iodevice.async_read_some(asio::buffer(buffer), callback);
            }
        };

    iodevice.async_read_some(asio::buffer(buffer), callback);

    io_svc.run();
}

See it Live On Coliru .

Sadly on Coliru it can't work because input is redirected from a non-stream. But if you run it interactively it will work and print the first 10 characters entered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM