使用 boost::asio 丢弃数据

Posted

技术标签:

【中文标题】使用 boost::asio 丢弃数据【英文标题】:Discarding data with boost::asio 【发布时间】:2011-11-02 07:07:18 【问题描述】:

我在异步模式下使用 boost::asio,我想跳过/丢弃/丢弃通过 TCP 发送给我的消息。我想这样做是因为我已经阅读了消息的标题,并且我知道这对我没有兴趣。该消息可能很大,因此我宁愿不为其分配空间,甚至最好根本不将其转移到用户空间。

我看到 boost::asio::null_buffers 但它似乎不适用于此处(请参阅https://svn.boost.org/trac/boost/ticket/3627)。

【问题讨论】:

这里有一个关于使用null_buffers的案例的SO帖子:***.com/questions/4686127/… 【参考方案1】:

据我所知,BSD 套接字接口没有为您提供此功能。您总是必须读入缓冲区。现在,为了不分配巨大的缓冲区,您可以做的是在循环中读入一个较小的缓冲区。像这样的:

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

这还没有通过编译器,所以可能有愚蠢的错别字,但它应该说明这一点。

【讨论】:

【参考方案2】:

Boost 的 Asio 是一个我自己还没有使用过的库。所以我不知道是否可以插入带有Sink 接口的任何东西。但如果是这样,boost 的null_sink 是否可以很好地满足您的情况...?

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

(它只会丢弃数据,因此您仍在用户空间中。如果有其他方法我会感到惊讶,但如果可以的话会很酷。)

【讨论】:

谢谢Hostile Fork,但是null_sink不符合作为asio缓冲区使用的要求。 啊,好吧。我从随意的阅读中认为这一切都是基于流...我看到一些 iostream 的东西被传递并与 boost::asio::stream_buf 交互。但看起来他们确实发明了自己的类,可以导出流接口但不能导入它们。 (我对设计的了解不够多,无法理解为什么不能将流用作缓冲区的逻辑,例如 strstream。)我将不得不编写一个基于 Asio 的程序!

以上是关于使用 boost::asio 丢弃数据的主要内容,如果未能解决你的问题,请参考以下文章

Boost.Asio 的同步和并发数据结构模式

boost::asio::streambuf 通过 https 检索 xml 数据

如何使用Boost.Asio读取WHOLE char类型捕获的数据

为啥 boost::asio::read 缓冲区数据大小小于读取大小?

boost.asio - 如果在不同的异步处理程序之间共享数据库类型对象,我是不是需要使用锁?

C++ 使用 Boost.asio 和 Beast 库在正文中发送数据