gberes
gberes

Reputation: 1169

Boost asio async_write callback doesn't get called

I'm trying to write a simple server to send messages asynchronously, but my callback for async_write doesn't get called. By the way, data is succesfully transmitted to the client.

Firs, my server initialisation code:

void Server::start()
{
    ioService = new boost::asio::io_service();
    acceptor = new tcp::acceptor(*ioService, tcp::endpoint(tcp::v4(), port));

    serverRunning = true;

    serverThread = new boost::thread(&Server::run, this);
    startAccept();
}

My start accept and accept handler methods:

void Server::startAccept()
{
    serverSocket = new tcp::socket(acceptor->get_io_service());

    acceptor->async_accept(*serverSocket,
        boost::bind(&Server::handleAccept, shared_from_this(),
            boost::asio::placeholders::error));
}

void Server::handleAccept( const boost::system::error_code& error )
{
    changeState(Connected);
}

The handleAccept method get called when i connect, the changeState method does nothing for now. After the client connected, i put some data to the toSend vector, and the server's thread sends them:

void Server::run(){
    while( serverRunning ){
        ioService->poll();

        if (toSend.size()>0 ){
            mtx.lock();
            for (int i=0; i<toSend.size(); i++){
              cout << "async write" << endl;
                boost::asio::async_write(*serverSocket, boost::asio::buffer(toSend.at(i)),
                        boost::bind(&Server::handleSend, shared_from_this(),
                            toSend.at(i),
                            boost::asio::placeholders::error,
                            boost::asio::placeholders::bytes_transferred));
            }
            toSend.clear();
            mtx.unlock();
        }
        usleep(1000);
    }
}

I can see "async write" messages coming on std out, and the client recieves the data as well. My handleSend method is just some cout now, but it never get called. Why?

Upvotes: 0

Views: 3757

Answers (1)

Igor R.
Igor R.

Reputation: 15075

If you really want to poll the io_service manually, do this after it gets some work, and call reset between the iterations.

Besides, do not call asio::async_write in a loop - the data won't arrive in the correct order. Instead, either prepare a single sequence of buffers and send it at once, or chain async_write - completion handler - async_write, as shown in the examples.

Upvotes: 5

Related Questions