使用增压缓冲区进行操作

时间:2012-05-27 17:35:36

标签: c++ boost buffer stdstring

我正在使用流协议编写服务器,所以我需要做一些事情,比如找到标题的结尾,复制它然后在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;
}

1 个答案:

答案 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