异步读写与设备文件

时间:2014-10-28 00:36:30

标签: c++ boost boost-asio

我正在将一些二进制数据写入类似/ 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;
    }

}

回调函数readhandler正在成功执行,但是我无法将控件从我的Callback函数转移到另一个类。

从设计角度来看是不对的。我需要处理从回调函数接收的消息以获得进一步的逻辑。我应该在这里使用另一个线程吗?

2 个答案:

答案 0 :(得分:1)

答案取决于设备的确切属性。查看您尝试使用的设备驱动程序的文档。如果设备支持非阻塞I / O,请使用O_NONBLOCK打开设备,并使用poll()等待设备可供读取或写入。

如果设备不支持非阻塞I / O,唯一可行的选择是使用单独的线程来读取和/或写入设备,并使用后台线程构建假装和行为的外观非阻塞数据源和接收器。

答案 1 :(得分:1)

查看此代码,您可能只想通过提升Asio对Posix流的支持来替换read(device,...)

#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();
}

查看 Live On Coliru

可悲的是,在Coliru上它无法正常工作,因为输入是从非流重定向的。但是如果以交互方式运行它,它将工作并打印输入的前10个字符。