I have two async write operations using boost::asio::async_write
boost::asio::async_write(socket, boost::asio::buffer(data1), function);
boost::asio::async_write(socket, boost::asio::buffer(data2), function);
Does boost guarantee that data will be written to the socket in the exact order in which the write operations were called? In this case, I need know, is data1 will be sent before data2? If not, how can such an order be guaranteed?
CodePudding user response:
Q. Does boost guarantee that data will be written to the socket in the exact order in which the write operations were called?
No, in fact it forbids this use explicitly:
This operation is implemented in terms of zero or more calls to the stream's async_write_some function, and is known as a composed operation. The program must ensure that the stream performs no other write operations (such as
async_write
, the stream'sasync_write_some
function, or any other composed operations that perform writes) until this operation completes.
Q. In this case, I need know, is data1 will be sent before data2? If not, how can such an order be guaranteed?
You use a strand and chained operations (starting the next async operation from the completion handler of the first).
A flexible way to do that without requiring a lot of tedious code is to use a queue with outbound messages
You can look through my answers for examples
Alternatively using coroutines (
asio::spawn
or c 20's withasio::co_spawn
) to hide the asynchrony:async_write(socket, boost::asio::buffer(data1), use_awaitable); async_write(socket, boost::asio::buffer(data2), use_awaitable);
(use
yield_context
for Boost Context based stackful coroutines when you don't have c 20)Lastly, keep in mind you can write buffer sequences:
async_write(socket, std::array { boost::asio::buffer(data1), boost::asio::buffer(data2) }, function);