Haatschii
Haatschii

Reputation: 9309

boost::asio packet order and contiguity

I am using boost::asio::ip::tcp::socketto send and receive data in a client/server application. I use simple selfmade data packets consisting of a header containing the size of the packet plus some flags and the "real" data. I send my packets using boost::asio::write. In some cases I have a lot of packets to send to one client. Naive the fastest option would be to send them all at once. E.g.

 async_write(socket, buffer(p[0].str(),p[0].size()), &callback);
 async_write(socket, buffer(p[1].str(),p[1].size()), &callback);
 async_write(socket, buffer(p[2].str(),p[2].size()), &callback);

But if I do it like this, is there a guarantee that my packets arrive as a whole at the client? So in the example if the first 4 bytes of the packet represent the size of the remaining packet, can I call four times

uint32 size;
read(socket, buffer(&size,4));
char data[size];
read(socket, buffer(data,size));

and be sure that each data contains one packet (appart from the size uint32)? Or would it work if I send the next packet in the callback function?

If this infact works one other question is about the ordering. Can I be sure that the order, the packets arrive at the client, is the same as the one I send them from the server?

Upvotes: 3

Views: 1313

Answers (1)

Sam Miller
Sam Miller

Reputation: 24174

First and foremost, TCP sockets operate on streams of data, not packets. Secondly the async_write() documentation explicitly states a single outstanding operation per socket can be in-flight:

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's async_write_some function, or any other composed operations that perform writes) until this operation completes.

You will need to chain your operations: invoke a second async_write() only after the completion handler for the first operation has been invoked.

Upvotes: 5

Related Questions