我正在使用流协议编写服务器,所以我需要做一些事情,比如找到标题的结尾,复制它然后在boost缓冲区中解析其他东西。当我发现使用字符串进行操作的最佳方法(在其中查找字符串,使用迭代器复制/删除等)是std :: string。但我正在使用char数组缓冲区。所以我需要有两个缓冲区 - char数组和std :: string - 每次我需要用缓冲区操作时我需要将char数组转换为std :: string,做我的东西然后将它转换回来使用std :: string.c_str()来char数组。我找到的另一种方法是使用streambuf(正如我之前在questition中提到的那样)然后创建istream / ostream并将其中的内容填充到std :: string(如documentation中所示)。
有了streambuf,我需要:
流缓冲
mutable_buffers_type
istream的
ostream的
和std :: string
但是使用char数组和std :: string我只需要:
char数字
std :: string
所以我认为使用streambuf会浪费内存(我需要为每个连接创建缓冲区)。我可以使用std :: string作为缓冲区吗?但是我认为可能有更好的方法来做到这一点。你能给我一个建议吗?
编辑:
我需要用我的缓冲区做这样的事情,但是char数组不提供像std :: string(erase,substr,...)这样的功能,所以我需要使用std :: string作为缓冲区。将它用作boost :: buffer的最佳方法是什么,或者解析这个代码的最佳方法是什么?
#include <iostream>
int main(int argc, char* argv[])
{
//"header" is header
//"end" is marking that this point is end of header
//"data" is data after header
//this all is sent in one packet which I receive to buffer
//I need to fill "headerend" to std::string header and then remove "headerend" from begining of buffer
//then continue parsing "data" which stay in buffer
std::string buffer = "headerenddata"; //I receive something like this
std::string header; //here I'll fill header (including mark of end of header)
//find end of header and include also mark of end of header which is "end" (+3)
int endOfHeader = int(buffer.find("end"))+3;
//fill header from buffer to string header
header = buffer.substr(0, endOfHeader);
//delete header from input buffer and keep data in it for next parsing
buffer.erase(buffer.begin(), buffer.begin()+endOfHeader);
//will be just "data" becouse header and mark of header are removed
std::cout << buffer << std::endl;
//will be "headerend" which is "header" and mark end of header which is "end"
std::cout << header << std::endl;
return 0;
}
答案 0 :(得分:3)
您可以使用std::string
作为参数构建boost::asio::buffer
。我通常使用char矢量(std::vector<char>
)。我认为处理它更容易,但这可能真的取决于代码的其余部分是如何设计的。
您也可以使用C++11 array。它的行为类似于向量,但它静态地分配空间(即,一旦创建了数组,底层缓冲区的大小就不会改变)。在某些情况下,这可能会给您带来一些性能优势。如果你不能使用C ++ 11,Boost还包括一个非常相似的类。
boost::asio::buffer
也接受普通的char数组(char buf[SIZE]
),但如果可能的话,使用前面提到的选项可能会更方便。
供参考,这里是boost::asio::buffer
的文档。
更新:为了避免从char[]
转换为string
,您可以使用vector
来接收和处理缓冲区(使用用于接收缓冲区的string
也可能有效,但我从未尝试过这样做。)
所以,接受你可以这样做:
vector<char> msg(N);
...
asio::read(socket, asio::buffer(msg), asio::transfer_at_least(N), ec);
然后,为了处理数据包并拆分头和数据,您可以使用迭代器,避免代码中{(1}}和substr
的O(n)复杂性操作。当然,erase
(或我的示例中为find
)无法避免:
search