Jukurrpa
Jukurrpa

Reputation: 4138

boost::asio async_read doesn't receive data or doesn't use callback

I am trying to receive data from a server application using boost asio's async_read() free function, but the callback I set for when the receiving is never called.

The client code is like this:

Client::Client()
{
  m_oIoService.run(); // member boost::asio::io_service
  m_pSocket = new boost::asio::ip::tcp::socket(m_oIoService);

  // Connection to the server
  [...]

  // First read
  boost::asio::async_read(*m_pSocket,
                          boost::asio::buffer((void*)&m_oData, sizeof(m_oData)),
                          boost::bind(&Client::handleReceivedData, this,
                                      boost::asio::placeholders::error,
                                      boost::asio::placeholders::bytes_transferred));
}

I tried with small data (a short string) and I can't get it to work. When I use the synchronous read function (boost::asio::read()) using the two same first parameters, everything works perfectly.

Am I missing something with the use of the io_service? I am still unsure about how it works.

Upvotes: 2

Views: 2693

Answers (1)

user405725
user405725

Reputation:

boost::asio::service::run () is a blocking call. Now, in your example it may or may not return immediately. In case it doesn't, you you are blocked even before you create a socket, and never call read, so cannot expect a callback. Otherwise, dispatch loop is exited, so no callbacks are ever delivered.

Read more about boost::asio::service::run (). I recommend you check out documentation including tutorial, examples and reference. It is worth going trough it in full to understand the concept.

Hope it helps!

P.S.: On a side note, your code is not exception safe. Beware that if constructor of the class fails with exception then destructor of that class instance is never called. Thus, you may leak at least m_pSocket if its type is not one of the "smart pointers". You should consider making it exception safe, moving the code to another method that should be called by user, or even wrapping this functionality with a free function.

Upvotes: 5

Related Questions