Reputation: 4138
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
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