7

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).

mpm
  • 1,066
  • 9
  • 23

2 Answers2

7

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.

Arvid
  • 10,915
  • 1
  • 32
  • 40
0

Boost's Asio is a library I haven't used myself yet. So I don't know if just anything with a Sink interface can plug in. But if so, would boost's null_sink work well enough for your situation...?

http://www.boost.org/doc/libs/1_46_1/libs/iostreams/doc/classes/null.html

(It would just throw the data away, so you're still in user space. I'd be surprised if there's a way to do otherwise, but would be cool if you could.)

  • Thank you, Hostile Fork, but the null_sink does not meet the requirements for use as an asio buffer. – mpm Aug 24 '11 at 13:58
  • Ah, oh well. I thought from casual reading it was all based on streams...I saw some `iostream` things being passed around and interacting with `boost::asio::stream_buf`. But it does look like they've invented their own class which can export stream interfaces but cannot import them. (I don't know enough about the design to understand the logic of why a stream couldn't be used as a buffer kind of like `strstream`.) I'll have to write an Asio based program sometime! – HostileFork says dont trust SE Aug 25 '11 at 21:48