4

I have the following class definition:

// SocketTypeT may be e.g. 'boost::asio::ip::tcp::socket'
template<class SocketTypeT> 
class Socket : public SocketTypeT, public boost::enable_shared_from_this< Socket<SocketTypeT> > {
[...]

Within this class I have the following method 'writeAsync':

void writeAsync(const std::string& strData) {               
            boost::asio::async_write(*this, boost::asio::buffer(strData),                                   
                                    boost::bind(&Socket::handle_write_async,
                                    shared_from_this(),
                                    boost::asio::placeholders::error,
                                    boost::asio::placeholders::bytes_transferred));
}

And finally the handler (also a class member function) used in 'writeAsync':

void handle_write_async(const boost::system::error_code& ec, std::size_t cntBytesSent) {
    cout << "handle_write_async" << endl;
    if (m_pSocketAsyncObserver) {
        m_pSocketAsyncObserver->handleAsyncWrite(connectionClosed, cntBytesSent, ec);
    }
}

Problem:

The data is successfully transmitted to the server, however 'handle_write_async' gets never called. What might be the reason for this?

Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
Anonymous
  • 4,617
  • 9
  • 48
  • 61
  • that code superficially looks okay - are you calling `run()` on the `io_service`? – Nim Nov 26 '15 at 11:30
  • 1
    A call of `run()` was missing. But the result is the same even with calling run. Is the call order relevant, e.g. do I have to call run before initializing `boost::asio::ip::tcp::socket` with the `io_service`-object? – Anonymous Nov 26 '15 at 11:55
  • `io_service::run()` is required to dispatch all asynchronous operations. Normally you can set everything up (socket, connect etc.) and then call run (as it's a blocking operation - unless you do it in another thread.) – Nim Nov 26 '15 at 11:57
  • In my case a call to `my_io_service.run()` does not block? – Anonymous Nov 26 '15 at 12:01
  • That means there are no asynchronous operations to execute - so there is nothing for the io_service to do.. – Nim Nov 26 '15 at 12:05
  • 1
    You have to call run *after* you called async_write. Run basically means "run jobs and call handlers until there are none left", so if you call it before async_write, there is just nothing to do. If that still does not work, could you provide your full example so we can investigate ? – mefyl Nov 26 '15 at 12:08
  • I identified the following behavior: When calling `run` for the first time after `async_write` my handler does not get called. I have to call `run` a second time. After the second call, my handler gets called. Each further `async_write` needs an additional call of `run` but one call is sufficient in this case. Is this behavior normal? Do I have to call `run` after each async_write by myself? – Anonymous Nov 26 '15 at 12:46
  • According to the documentation (http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/io_service/run/overload1.html) one has to call `reset` after `run` completed once before calling `run` again. If I call `reset` before `run` everything works as expected. So in any case where I called `async_write` it seems that one has to call `reset` followed by `run` or calling `run` twice. Seems strange to me. – Anonymous Nov 26 '15 at 12:55
  • @Anonymous make sure that `run` is called on the **`socket`'s** `io_service` – Necktwi Jan 29 '17 at 17:13

1 Answers1

0

For continuous execution of run you need to supply io_service::work object. Please read this question

Community
  • 1
  • 1
Roman Zaitsev
  • 1,328
  • 5
  • 20
  • 28