The relative order of the async calls is respected if you actively ensure
that. If you request a size_read and data_read, both async, one after
another without waiting for the first to complete, then there is no
guarantee that they will be performed in the right order... to do that one could write something like this:
/* Reads the size of the incoming data */
void TCP_connection::read_header()
{
unsigned char* header = new unsigned char[header_size];
//header_size is a const defined by your application, you could use for example sizeof(unsigned short)
boost::asio::async_read(socket, boost::asio::buffer(header, header_size),
boost::bind(&TCP_connection::OnSizeRead, this,
boost::asio::placeholders::error,
header, boost::asio::placeholders::bytes_transferred));
}
/* Starts the data receive */
void TCP_connection::onSizeRead(const boost::system::error_code& error, const unsigned char* header, std::size_t bytes)
{
if(!error)
{
unsigned short message_length;
memcpy(&message_lenght, header, sizeof(header_size));
if(message_lenght > 0)
{
unsigned char* data = new unsigned char[message_length];
boost::asio::async_read(socket, boost::asio::buffer(data, message_length),
boost::bind(&TCP_connection::onDataRead, this,
boost::asio::placeholders::error,
data, boost::asio::placeholders::bytes_transferred));
}
}
delete[ ] header;
}
This ensures that the size of
the data is always read first. Also, note that in this example i use
buffer allocation with the operator new(). You might want to use
buffers already allocated and then instead of deleting them, just set
them free to reuse. The only requirement is that you have enough space
to accomodate the data and that the buffer will outlive the call to the
async operation.