Software‎ > ‎

Using boost::asio for non-blocking IO with 3rd party API

posted Feb 8, 2011, 10:18 PM by Andrew Jessop   [ updated Dec 23, 2011, 3:45 AM ]
Recently I have had to deal with a C++ library that maintains control of the creation, binding, connection, buffering etc of a TCP connection and associated file descriptor.  I wanted to use the boost::asio framework for this application and below is how I went about it.

Update: This doesn't seem to be using epoll() or select() as I had intended.  The code will need changing.

#include <boost/asio.hpp>
#include <boost/bind.hpp>

#include <custom/api.hh>

class
APIWrapper

{
public:
    ...
    void connect()
    {
        // other API stuff here
        mySocket.assign(boost::asio::ip::tcp::v4(), api->fd());
        boost::asio::ip::tcp::socket::non_blocking_io nb(true);
        mySocket.io_control(nb);
        
        startIO();

    }

    void startIO()
    {
        mySocket.async_read_some(boost::asio::null_buffers(),
            boost::bind(&APIWrapper::ioRead, this)
        );
        mySocket.async_write_some(boost::asio::null_buffers(),
            boost::bind(&APIWrapper::ioWrite, this)
        );
    }

    void action()
    {
        // Since the API either directly, or via a buffer, writes to the socket
        // nothing else has to be done here. We will get the ioWrite() callback
        // from boost::asio once we're ready to write data back out.
        api->action();
    }
    ...
private:
    boost::asio::ip::tcp::socket mySocket;
    API *api;

    void ioRead()
    {  
        api->read();
    }
    void ioWrite()
    {
        api->write();
    }
};

int main()
{
    // Create the main service
    boost::asio::io_service io_service;
    boost::asio::io_service::work work(io_service);

    // Connect via API
    APIWrapper client;
    client.connect();

    // Perform some initial action
    client.action();

    // Start the main event loop
    io_service.run();


    return 0;
}

Comments