提升 ASIO 流缓冲
我对 boost asio::streambuf 类中的输入序列和输出序列感到困惑.
I am confused about the input sequence and output sequence in boost asio::streambuf classes.
根据文档中的代码示例(用于发送数据),表示输入序列的缓冲区用于写入套接字,而表示输出序列的缓冲区用于读取.
According to the code examples (for sending data) in the documentation it seems that the buffer representing the input sequence is used for writting to socket and the one representing the output sequence is used for reading.
示例 -
boost::asio::streambuf b;
std::ostream os(&b);
os << "Hello, World!
";
// 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
与C++标准中定义的类似,在标准模板库的各个类中使用,其中数据写入输出流,数据从输入流读取.例如,可以使用 std::cout.put()
写入输出流,使用 std::cin.get()
从输入流中读取.
The nomenclature for boost::asio::streambuf
is similar to that of which is defined in the C++ standard, and used across various classes in the standard template library, wherein data is written to an output stream and data is read from an input stream. For example, one could use std::cout.put()
to write to the output stream, and std::cin.get()
to read from the input stream.
手动控制streambuf
输入输出序列时,数据的大致生命周期如下:
When manually controlling the streambuf
input and output sequences, the general lifecycle of data is as follows:
- 缓冲区使用
prepare()
用于输出序列. - 将数据写入输出序列的缓冲区后,数据将为
commit()
.提交的数据将从输出序列中删除,并附加到可以从中读取数据的输入序列中. - 从通过
data()
. - 读取数据后,可以通过
consume()
.
当使用 Boost.Asio 操作对 streambuf
或使用 streambuf
的流对象进行操作时,例如 std::ostream
,底层的输入和输出序列将得到妥善管理.如果为某个操作提供缓冲区,例如将 prepare()
传递给读操作或将 data()
传递给写操作,则必须显式处理commit()
和 consume()
.
When using Boost.Asio operations that operate on streambuf
or stream objects that use a streambuf
, such as std::ostream
, the underlying input and output sequences will be properly managed. If a buffer is provided to an operation instead, such as passing passing prepare()
to a read operation or data()
to a write operation, then one must explicitly handle the commit()
and consume()
.
这是示例代码的注释版本,它直接从 streambuf
写入套接字:
Here is an annotated version of the example code which writes directly from an streambuf
to a socket:
// 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!
".
os << "Hello, World!
";
// 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",但尚未读取:
And here is the annotated example for reading from a socket directly into an streambuf
. The annotations assume that the word "hello" has been received, but not yet read, on the socket:
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;
注意在上面的例子中,steam 对象如何处理提交和消耗流缓冲的输出和输入序列.但是,当使用缓冲区本身时(即 data()
和 prepare()
),需要显式处理提交和消耗的代码.
Note how in the above examples, the steam objects handled committed and consuming the streambuf's output and input sequences. However, when the buffers themselves were used (i.e. data()
and prepare()
), the code needed to explicitly handle commits and consumes.
相关文章