Question

I have some simple questions, I have a client-server application and data sent on the wire.

I'd like to be able to recover the data and handle it properly.

struct T1
{
   int id;
   int foo;
};

struct T2
{
  int id;
  char foo;
  int bar;
};

Let's take these structures, they are sent on the network preceded by an int which will tell if either T1 or T2 follows. If the client sends me T1, then sends me T2, do I have the assurance that I can read a full structure with asio::ip::tcp::socket.async_read() ? I'd like to set up a handler which will handle a single struct, however what will happen if I'm unable to read everything in a single async_read() ?

The asynchronous operation will continue until one of the following conditions is true:

  • The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
  • An error occurred.

Will it discard the data that cannot be read ? will it trigger another async_read ? And, am I assured that an async_read will only get one ID+structure if my client sends me sequentially the ID+structure ? Or may the OS optimize things and put them both in the same paquet ? As you may have seen, I'm a little confused, I'd like to make the right decisions when designing a server/client application, any help will be appreciated.

Thank you.

Was it helpful?

Solution

EDIT: Thanks to @timo for pointing out a mistake. async_read won't complete until an entire struct is read, so you don't need to loop. Otherwise, my answer is the same. Nothing will be lost, regardless of how the TCP protocol breaks up or coalesces the data.

If there isn't enough data in the TCP buffers to fill your input buffer, the read will simply fetch whatever is available, and report the number of bytes fetched. What happens next is up to you. You might have enough data in the fetched bytes to decide you don't want to continue, so asio makes no assumptions. If you haven't read enough bytes to comprise a complete structure, then initiate a further async_read, repeating the process until you have enough bytes or something dies.

I'm not sure what you mean by, "unable to read everything." two possible meanings come to mind:

  1. The amount of data that's available to read doesn't fill a struct. In this case, you simply do another read_async to wait for more data to arrive.
  2. The struct doesn't absorb all that data that has arrived. The TCP stack will simply buffer unread data until you get around to reading it.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top