boost::asio
各种read
和write
函数和方法接受boost::asio::buffer
。根据{{3}},可变std::string
无法包含在boost::asio::buffer
中,因此不能用于asio的read
函数。这可能是因为std::string
不允许对其内部缓冲区进行可变访问(这在前面已经讨论过buffer's documentation)。
这很遗憾,因为std::string
是在C ++中表示可变数据缓冲区的便捷方式。没有它,我们要么留下POD数组,boost::array
和std::vector<char>
。前两个对于可变长度消息不方便。 std::vector<char>
可以工作,但这是一种不自然的方式来携带数据缓冲区(*)
问题:
std::string
和boost::asio
是否有其他替代方法可用于读取缓冲区?我在这里错过了什么吗?std::vector<char>
。是因为它保证其内部缓冲区在内存中是连续的,并允许使用&vec[0]
对其进行可变访问吗?提前致谢
(*)恕我直言。例如,请查看protobuf
序列化 - 它将序列化提供到std::string
但不提供std::vector<char>
,至少不是明确的。
编辑:毕竟我最终使用vector<char>
。 protobuf
允许通过vector<char>
调用序列化为SerializeToArray
,该调用带有指针(&vec[0]
可以在那里传递)。
答案 0 :(得分:8)
使用&str[0]
对字符串缓冲区的可变访问在所有已知实现上都能正常工作,并且即将推出的C ++ 0x标准化的措辞使其正式允许。
尽管如此,我认为你认为std::vector
是一个可变长度缓冲区的不自然表示你是疯了。
答案 1 :(得分:5)
这是回答Eli的评论
我没有提到我的asio :: streambuf 最初的问题,确实是因为它 我不是100%清楚如何使用它 固定大小的读取和asio。可以 你指出一个例子(或添加一个作为 答案)显示如何阅读 固定长度的块到一个
std::sstream
?
以下是关于使用asio::streambuf
和Boost.Serialization
的{{3}}。 asio a previous answer也有一个同步读取的例子:
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;
答案 2 :(得分:2)
1)通过检查asio::buffer()
函数,返回mutable_buffers_1
的重载,可以找到替代方案。更灵活(但可能是次优)选项是asio::streambuf
,对(async_)read_until
很有用。
如果你有固定大小的字段协议,你可以使用asio::mutable_buffer
数组。 e.g。
using boost::asio;
int i;
short s;
char data[data_size]; // data_size is defined elsewhere
boost::array<asio::mutable_buffer, 3> bufs = {
asio::buffer(&i, 4),
asio::buffer(&s, 2),
asio::buffer(data, data_size)
};
asio::read(socket, buffer(bufs)); // socket defined elsewhere
2)您已经对这个问题提出了很好的答案:"How to asynchronously read to std::string using Boost::asio?"