I'm using boost::asio in asynchronous mode and I'd like to skip/discard/drop a message that has been sent to me over TCP. I want to do this because I've already read the header for the message and I know that it is of no interest to me. The message may be large so it I would prefer not to allocate space for it and even better not to transfer it into user space at all.
I see boost::asio::null_buffers but it does not appear to be applicable here (see https://svn.boost.org/trac/boost/ticket/3627).
As far as I know, the BSD socket interface doesn't give you this functionality. You always have to read into a buffer. Now, what you can do in order to not allocate a huge buffer is to read into a smaller buffer in a loop. Something like this:
void skip_impl(tcp::socket& s, int n, boost::function<void(error_code const&)> h
, char* buf, error_code const& ec, std::size_t bytes_transferred)
{
assert(bytes_transferred <= n);
n -= bytes_transferred;
if (ec || n == 0) {
delete[] buf;
h(ec);
return;
}
s.async_read_some(boost::asio::buffer(temp, std::min(4096, n))
, boost::bind(&skip_impl, boost::ref(s), n, h, temp, _1, _2));
}
void async_skip_bytes(tcp::socket& s, int n, boost::function<void(error_code const&)> h)
{
char* temp = new char[4096];
s.async_read_some(boost::asio::buffer(temp, std::min(4096, n))
, boost::bind(&skip_impl, boost::ref(s), n, h, temp, _1, _2));
}
This has not been passed through a compiler, so there might be silly typos, but it should illustrate the point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With