与boost :: asio一起使用的std :: string的替代方法

时间:2011-03-09 15:49:24

标签: c++ boost-asio

boost::asio各种readwrite函数和方法接受boost::asio::buffer。根据{{​​3}},可变std::string无法包含在boost::asio::buffer中,因此不能用于asio的read函数。这可能是因为std::string不允许对其内部缓冲区进行可变访问(这在前面已经讨论过buffer's documentation)。

这很遗憾,因为std::string是在C ++中表示可变数据缓冲区的便捷方式。没有它,我们要么留下POD数组,boost::arraystd::vector<char>。前两个对于可变长度消息不方便。 std::vector<char>可以工作,但这是一种不自然的方式来携带数据缓冲区(*)

问题:

  1. std::stringboost::asio是否有其他替代方法可用于读取缓冲区?我在这里错过了什么吗?
  2. 我想知道为什么在可变缓冲区中支持std::vector<char> 。是因为它保证其内部缓冲区在内存中是连续的,并允许使用&vec[0]对其进行可变访问吗?
  3. 提前致谢


    (*)恕我直言。例如,请查看protobuf序列化 - 它将序列化提供到std::string但不提供std::vector<char>,至少不是明确的。


    编辑:毕竟我最终使用vector<char>protobuf允许通过vector<char>调用序列化为SerializeToArray,该调用带有指针(&vec[0]可以在那里传递)。

3 个答案:

答案 0 :(得分:8)

使用&str[0]对字符串缓冲区的可变访问在所有已知实现上都能正常工作,并且即将推出的C ++ 0x标准化的措辞使其正式允许。

尽管如此,我认为你认为std::vector是一个可变长度缓冲区的不自然表示你是疯了。

答案 1 :(得分:5)

这是回答Eli的评论

  

我没有提到我的asio :: streambuf   最初的问题,确实是因为它   我不是100%清楚如何使用它   固定大小的读取和asio。可以   你指出一个例子(或添加一个作为   答案)显示如何阅读   固定长度的块到一个   std::sstream

以下是关于使用asio::streambufBoost.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?"