我正在努力理解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的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()时。我把它放在我的处理程序中的异步代码中,主要是因为我所用的例子中有它,但我也不确定是否要调用它。当我尝试使用带有stringstream's和std::string's的commit()时,commit()似乎没有发挥作用--在不调用streambuf上的commit()的情况下,任何事情都不会停止或卡住。
有人能帮我解决这个问题吗?
发布于 2014-12-06 17:30:38
Asio定义了许多接受( xxx)的asio::streambuf,他们关心prepare和commit。
另一方面,如果您想将asio::streambuf与接受概念模型的低层函数一起使用,则必须调用streambuf::prepare(),后者返回符合MutableBufferSequence概念的对象,将该对象作为缓冲区传递,并在函数填充该对象后调用commit()。
在这两种情况下,在您从n读取了streambuf的数据字节之后,您必须调用consume(n) -以便使用输入序列。
发布于 2014-12-06 15:57:28
read_until在他的实现中使用read_some。因此,read_some调用streambuf::commit和read_until (直接)。
通常您不需要调用commit和consume,但是如果您想对缓冲区数据做一些事情,这可以是一种方法。例如,如果您使用的是二进制协议,则不能正确地使用read_until进行检查。
https://stackoverflow.com/questions/27325843
复制相似问题