首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >何时调用boost::asio::streambuf::消费()和boost::asio::streambuf::commit()?

何时调用boost::asio::streambuf::消费()和boost::asio::streambuf::commit()?
EN

Stack Overflow用户
提问于 2014-12-05 22:41:10
回答 2查看 3.6K关注 0票数 10

我正在努力理解boost::asio::streambuf::consume()boost::asio::streambuf::commit()调用。在文档中,我们有例子,

代码语言:javascript
复制
boost::asio::streambuf b;
std::ostream os(&b);
os << "Hello, World!\n";

// try sending some data in input sequence
size_t n = sock.send(b.data());

b.consume(n); // sent data is removed from input sequence

代码语言:javascript
复制
boost::asio::streambuf b;

// reserve 512 bytes in output sequence
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);

size_t n = sock.receive(bufs);

// received data is "committed" from output sequence to input sequence
b.commit(n);

std::istream is(&b);
std::string s;
is >> s;

我理解这两个调用,就像我理解文档中关于它们的内容一样--调用consume()boost::asio::streambuf中的输入序列中删除字符,并调用commit()将字符从boost::asio::streambuf的输出序列移动到其输入序列。

我什么时候才能叫这些?看看boost::asio::read_until()的源代码,我们有

代码语言:javascript
复制
template <typename SyncReadStream, typename Allocator>
std::size_t read_until(SyncReadStream& s,
    boost::asio::basic_streambuf<Allocator>& b, char delim,
    boost::system::error_code& ec)
{
  std::size_t search_position = 0;
  for (;;)
  {
    // Determine the range of the data to be searched.
    typedef typename boost::asio::basic_streambuf<
      Allocator>::const_buffers_type const_buffers_type;
    typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
    const_buffers_type buffers = b.data();
    iterator begin = iterator::begin(buffers);
    iterator start_pos = begin + search_position;
    iterator end = iterator::end(buffers);

    // Look for a match.
    iterator iter = std::find(start_pos, end, delim);
    if (iter != end)
    {
      // Found a match. We're done.
      ec = boost::system::error_code();
      return iter - begin + 1;
    }
    else
    {
      // No match. Next search can start with the new data.
      search_position = end - begin;
    }

    // Check if buffer is full.
    if (b.size() == b.max_size())
    {
      ec = error::not_found;
      return 0;
    }

    // Need more data.
    std::size_t bytes_to_read = read_size_helper(b, 65536);
    b.commit(s.read_some(b.prepare(bytes_to_read), ec));
    if (ec)
      return 0;
  }
}

您可以看到,正如文档所述,boost::asio::read_until()是按照SyncReadStreamread_some()实现的。

对我来说,这说明

  1. SyncReadStream::read_some()不调用boost::asio::streambuf::commit()
  2. boost::asio::read_until()确实调用了boost::asio::streambuf::commit()
  3. 无论是在boost::asio::read_until()的文档中,还是在SyncReadStream的文档中,这些文件似乎都没有被记录下来。
  4. 我不知道我是不是该给boost::asio::streambuf::commit()打电话?

使用我的同步代码,我显然不需要它,尤其是当我调用空闲函数boost::asio::read()boost::asio::read_until()时。我把它放在我的处理程序中的异步代码中,主要是因为我所用的例子中有它,但我也不确定是否要调用它。当我尝试使用带有stringstream's和std::string's的commit()时,commit()似乎没有发挥作用--在不调用streambuf上的commit()的情况下,任何事情都不会停止或卡住。

有人能帮我解决这个问题吗?

EN

回答 2

Stack Overflow用户

发布于 2014-12-06 17:30:38

Asio定义了许多接受( xxx)asio::streambuf,他们关心preparecommit

另一方面,如果您想将asio::streambuf与接受概念模型的低层函数一起使用,则必须调用streambuf::prepare(),后者返回符合MutableBufferSequence概念的对象,将该对象作为缓冲区传递,并在函数填充该对象后调用commit()。

在这两种情况下,在您从n读取了streambuf的数据字节之后,您必须调用consume(n) -以便使用输入序列。

票数 4
EN

Stack Overflow用户

发布于 2014-12-06 15:57:28

read_until在他的实现中使用read_some。因此,read_some调用streambuf::commitread_until (直接)。

通常您不需要调用commitconsume,但是如果您想对缓冲区数据做一些事情,这可以是一种方法。例如,如果您使用的是二进制协议,则不能正确地使用read_until进行检查。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27325843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档