我试图理解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()
是根据SyncReadStream
&#39; s read_some()
实现的。
对我来说,那就是
SyncReadStream::read_some()
不会致电boost::asio::streambuf::commit()
boost::asio::read_until()
致电boost::asio::streambuf::commit()
boost::asio::read_until()
的文档中。SyncReadStream
? 使用我的同步代码我似乎不需要它,而不是在我调用自由函数boost::asio::streambuf::commit()
和boost::asio::read()
时。我在处理程序中的异步代码中使用它主要是因为我使用的示例有它,但我也不确定是否也可以调用它。当我尝试使用boost::asio::read_until()
boost::asio::streambuf
和stringstream
时,std::string
似乎没有发挥作用 - 没有在commit()
上调用commit()
,就不会停止或停止任何操作。
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:4)
Asio定义了一些接受asio::streambuf
的{{3}},他们关注prepare
和commit
。
另一方面,如果您要asio::streambuf
使用auxiliary free functions (read_xxx)接受lower-level functions的型号,则必须致电streambuf::prepare()
,返回符合MutableBufferSequence
概念的对象,将此对象作为缓冲区传递,并在函数填充后调用commit()。
在这两种情况下,在您从n
读取streambuf
个字节的数据后,您必须调用consume(n)
- 才能使用输入序列。
答案 1 :(得分:1)
read_until
在其实施中使用read_some
。因此,read_some
调用streambuf::commit
和read_until
不会(直接)。
通常您不需要调用commit
和consume
,但如果您想对缓冲区数据执行某些操作 - 这可以是一种方法。例如,如果您使用二进制协议,则无法使用read_until
正确检查。