0
votes

Consider a client sending data to a server using TCP, with boost::asio, in "synchronous mode" (aka "blocking" functions).

Client code (skipped the part about query and io_service):

tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket( io_service );
boost::asio::connect( socket, endpoint_iterator );
std::array<char, 1000> buf = { /* some data */ };
size_t n = socket.send( boost::asio::buffer(buf) );

This will send the whole buffer (1000 bytes) to the connected machine.

Now the server code:

tcp::acceptor acceptor( io_service, tcp::endpoint( tcp::v4(), port ) );
tcp::socket socket( io_service );
boost::system::error_code err;
std::array<char, 500> buff;
size_t n = socket.read_some( boost::asio::buffer(buff), err );
std::cout << "err=" << err.message() << '\n';
  • What this does: client sends 1000 bytes through the connection, and server attempts to store it in a 500 bytes buffer.
  • What I expected: an server error status saying that buffer is too small and/or too much data received.
  • What I get: A "Success" error value, and n=1000 in the server.

What did I miss here ? Can't ASIO detect the buffer overflow ? Should I proceed using some other classes/functions (streams, maybe?)

Refs (for 1.54, which is the one I use):

2

2 Answers

1
votes

You're seriously misunderstanding TCP.

TCP is a byte stream. There's no packet boundary inside a TCP stream. Until you close the socket, all bytes form a single stream. (unlike UDP)

Boost.Asio knows this. As long as the stream is open, it can't say how big the stream will eventually be. If you've got a 500 byte buffer, Boost Asio can fill it with the first 500 bytes of the (potentially unbounded) TCP stream.

However, read_some just looks at what's already available. In your case, with just 1000 bytes, it's entirely expected that the whole 1000 bytes are available on your network card. There's no error in that part. It jsut doesn't fit in your buffer, but that's not a problem on the network side.

Neither TCP nor UDP have a way to communicate back that the receiver was expecting a smaller packet. That's application-level logic, and you handle it on the application level. For instance, HTTP has 413 Payload Too Large. Therefore, Boost.Asio doesn't offer a standard mechanism.

0
votes

You did receive 500 bytes and may read the last 500 bytes by calling asio again. Just saying this as it seems to me that you misundertood the behaviour of asio.