提升ASIO streambuf

12

我对boost asio::streambuf类中的输入序列和输出序列感到困惑。

根据文档中(发送数据的)代码示例,似乎用于写入套接字的缓冲区代表输入序列,而用于读取的缓冲区代表输出序列。

示例 -

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

现在,是否存在术语命名问题?

2个回答

15

boost::asio::streambuf的命名方式类似于C++标准中定义的命名方式,并在标准模板库中的各种类中使用,其中数据被写入输出流并从输入流中读取。例如,可以使用std::cout.put()将数据写入输出流,并使用std::cin.get()从输入流中读取数据。

当手动控制streambuf输入和输出序列时,数据的一般生命周期如下:

  • 使用prepare()为输出序列分配缓冲区。
  • 将数据写入输出序列的缓冲区后,数据将被commit()。已提交的数据从输出序列中删除,并附加到输入序列中以供读取。
  • 通过data()获得从输入序列的缓冲区中读取的数据。
  • 一旦读取了数据,就可以通过consume()从输入序列中删除它。
当使用Boost.Asio操作来操作streambuf或使用streambuf的流对象(例如std :: ostream)时,底层的输入和输出序列将被正确管理。如果向操作提供缓冲区,例如将prepare()传递给读取操作或data()传递给写入操作,则必须显式处理commit()和consume()。
下面是一个示例代码的注释版本,它直接从streambuf写入套接字:
// The input and output sequence are empty.
boost::asio::streambuf b;
std::ostream os(&b);

// prepare() and write to the output sequence, then commit the written
// data to the input sequence.  The output sequence is empty and
// input sequence contains "Hello, World!\n".
os << "Hello, World!\n";

// Read from the input sequence, writing to the socket.  The input and
// output sequences remain unchanged.
size_t n = sock.send(b.data());

// Remove 'n' bytes from the input sequence. If the send operation sent
// the entire buffer, then the input sequence would be empty.
b.consume(n);

以下是直接从套接字读取到streambuf的示例注释。 注释假设单词“hello”已在套接字上接收但尚未读取:
boost::asio::streambuf b;

// prepare() 512 bytes for the output sequence.  The input sequence
// is empty.
auto bufs = b.prepare(512);

// Read from the socket, writing into the output sequence.  The
// input sequence is empty and the output sequence contains "hello".
size_t n = sock.receive(bufs);

// Remove 'n' (5) bytes from output sequence appending them to the
// input sequence.  The input sequence contains "hello" and the
// output sequence has 507 bytes.
b.commit(n);

// The input and output sequence remain unchanged.
std::istream is(&b);
std::string s;

// Read from the input sequence and consume the read data.  The string
// 's' contains "hello".  The input sequence is empty, the output
// sequence remains unchanged.
is >> s;

请注意在上述示例中,蒸汽对象处理了流缓冲区的输出和输入序列的提交和消耗。然而,当使用缓冲区本身(即data()prepare())时,代码需要明确处理提交和消费。

如何正确理解 std::ostream os(&b); - John

9

"万物皆相对"

阿尔伯特·爱因斯坦

文档中写道:

写入 basic_streambuf 对象的输出序列的字符将附加到同一对象的输入序列。

streambuf 的角度来看,它将从其输出序列读取并写入其输入序列,这可能看起来有点倒置,但您可以将 streambuf 视为使事情变得清晰的管道

现在从用户(使用 streambuf 的任何内容,包括套接字)的角度来看,您将写入 streambuf 的输出序列并从其输入序列中读取,这似乎更自然。

所以是的,就像左右取决于你面对什么一样,根据你从哪一侧观察,输入和输出也会被倒置。

"不要相信你在互联网上读到的每个引用,因为我完全没有说过那句话"

阿尔伯特·爱因斯坦


1
这应该是问题的答案。+1 - ahmed allam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接