Reputation: 43
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?
Upvotes: 1
Views: 1701
Reputation: 392911
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 with asio::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);
Upvotes: 2