2014-12-05 206 views
9

我试图了解boost::asio::streambuf::consume()boost::asio::streambuf::commit()调用。在文档中,我们有例子,何时调用boost :: asio :: streambuf :: consume()和boost :: asio :: streambuf :: commit()?

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 

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()源,我们有

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“ s文档。
  4. 我不知道我是否应该调用boost::asio::streambuf::commit()

与我的同步代码我当然似乎并不需要它,而不是当我打电话免费功能boost::asio::read()boost::asio::read_until()。我在我的处理程序中使用异步代码,主要是因为我使用的示例有它,但是我不确定是否要调用它。当我尝试使用boost::asio::streambufstringstreamstd::string时,commit()似乎没有起作用 - 没有任何事情会在streambuf上调用commit()而停止或停止。

任何人都可以为我解决这个问题吗?

+0

我希望看到一些关于此的明确文件。我找不到任何东西。 – EML 2017-04-11 15:30:53

回答

1

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

通常情况下,您不需要拨打commitconsume,但是如果您想对缓冲区数据执行某些操作,则可以这样做。例如,如果您使用二进制协议,无法通过read_until进行正确检查。

4

Asio定义了一个auxiliary free functions (read_xxx),它接受asio::streambuf,他们关心preparecommit它。

在另一方面,如果你想使用asio::streambuflower-level functions接受的MutableBufferSequence concept模型,你必须调用streambuf::prepare(),它返回满足MutableBufferSequence概念的对象,通过这个对象作为一个缓冲区,并经过该函数填充它 - 调用commit()。

在这两种情况下,当您读取streambufn字节的数据后,您必须调用consume(n) - 以消耗输入序列。