I'm implementing TCP server that uses both asio socket.async_read() and boost::asio::async_read_until() methods for asynchronous reading data from socket. Both use the same handler for reading data from boost::asio::streambuf.
The handler that perfectly works invoked via async_read() :
void handle_read(const boost::system::error_code& ec, std::size_t ytes_transferred) )
{
m_request_buffer.commit(bytes_transferred);
boost::asio::streambuf::const_buffers_type rq_buf_data = m_request_buffer.data();
std::vector<uint8_t> dataBytes(boost::asio::buffers_begin(rq_buf_data), boost::asio::buffers_begin(rq_buf_data) + bytes_transferred);
//process data here
m_request_buffer.consume(bytes_transferred);
bytes_transferred = 0;
}
My server depending on processing of data may shutdown connection or continue reading via the same socket.
But, if handle_read() is called from the 2-nd boost::asi::async_read_until() call, I'm getting a number of zero's in dataBytes and then valid data goes.
I tried a simple test-case and found out that after writing data to streambuf, and commit() + consume() the data in streambuf still keeps previous buffer.
So, is there any way to clear data in boost::asio::streambuf and reuse it in boost::asio::async_read_until() ?
If compiled with USE_STREAM=1, the live example works fine. But what std::istream does different comparing with buffer consume() ?
When using Boost.Asio operations that operate on
streambuf
or stream objects that use astreambuf
, such asstd::ostream
andstd::istream
, the underlying input and output sequences will be properly managed. If a buffer is provided to an operation instead, such as passing passingprepare()
to a read operation ordata()
to a write operation, then one must explicitly handle thecommit()
andconsume()
.The issue in the example is that it violates the API contract, causing uninitialized memory to be committed to the input sequence. The
commit()
documentation states:The use of the
std::ostream
between theprepare()
andcommit()
violates this contract, as it will modify the input sequence:Here is a complete example demonstrating using streambuf with annotated comments:
Output:
For more information on streambuf usage, consider reading this answer.