当前位置: 首页 > 知识库问答 >
问题:

使用boost缓冲区进行操作

赵英范
2023-03-14

我正在使用流协议编写服务器,所以我需要做一些事情,比如找到标题的结尾,复制它,然后在提升缓冲区中解析其他东西。当我发现使用字符串操作的最佳方法(在其中找到字符串,使用迭代器复制/删除等等)是std::字符串。但是我使用的是char数组缓冲区。所以我需要有两个缓冲区——char数组和std::字符串——每次我需要使用缓冲区进行操作时,我需要将char数组转换为std::字符串,完成我的工作,然后使用std::字符串将其转换回char数组。c_str()。我发现的另一种方法是使用stream buf(正如我在之前的问题中所问的),然后创建istream/ostream并将其内容填充到std::字符串(如留档所示)。使用Strebuf,我需要:
Strebuf
mutable_buffers_type
istream
ostream
和std::string
但是使用char数组和std::string,我只需要:
char数组
std::string

所以我认为使用streambuf是对内存的浪费(我需要为每个连接创建缓冲区)。我可以使用std::string作为boost buffer吗?然而,我认为可能有更好的方法来做到这一点。你能给我一个建议吗?

编辑:

我需要用我的缓冲区做类似的事情,但是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个答案

富辰阳
2023-03-14

您可以使用<code>std::string。我通常使用字符向量(std::vector

您也可以使用C11数组。它的行为类似于向量,但它静态地分配空间(即,一旦创建数组,底层缓冲区的大小就无法更改)。在某些情况下,这可能会给您带来一些性能优势。如果您不能使用C11,Boost还包括一个非常类似的类。

boost::asio::buffer也接受普通字符数组(char-buf[SIZE]),但如果可能的话,使用前面提到的选项可能更方便。

作为参考,这里是<code>boost::asio::buffer</code>的文档。

更新:为了避免从char[]字符串的转换,您可以使用向量来接收和处理缓冲区(使用字符串接收缓冲区也可能有效,但我从未尝试过)。

因此,对于接收,您可以:

vector<char> msg(N);
...
asio::read(socket, asio::buffer(msg), asio::transfer_at_least(N), ec);

然后,为了处理数据包并拆分标头和数据,您可以使用迭代器,避免代码中具有O(n)复杂性的操作(子str擦除)。当然,查找(或在我的示例中搜索)是无法避免的:

string end_marker = "end";
auto it = search(msg.begin(), msg.end(), end_marker.begin(), end_marker.end());

process_header(msg.begin(), it + 2);
process_data(it + 3, msg.end());

 类似资料:
  • 问题内容: 在编写用于OpenGL库的Matrix类时,我遇到了一个问题,即使用Java数组还是使用Buffer策略存储数据(JOGL为Matrix操作提供直接缓冲区复制)。为了对此进行分析,我编写了一个小型性能测试程序,该程序比较了Arrays vs Buffers和Direct Buffers上循环和批量操作的相对速度。 我想在这里与您分享我的结果(因为我发现它们很有趣)。请随时发表评论和/或

  • 我正在使用JOGL,但这个问题一般适用于OpenGL。似乎存在类似的问题,但它们要么针对GLSL代码,要么与复制帧缓冲区的内容有关,要么是一般建议-使用帧缓冲区对象,而不是。 我正在做一些阴影映射。如何使用帧缓冲对象将深度通道直接渲染到纹理? 能否请你贴一段初始化纹理和帧缓冲对象的代码,以及渲染场景前初始化一切的代码? 目前,我使用<code>glCopyTexSubImage2D<code>。我

  • 纯JavaScript是Unicode友好的,但二进制数据却不是这样。 在处理TCP流或文件系统时,必须处理八位字节流。 Node提供了Buffer类,它提供了存储类似于整数数组的原始数据的实例,但对应于V8堆外部的原始内存分配。 Buffer类是一个全局类,可以在应用程序中访问而无需导入缓冲区模块。 创建缓冲区 节点缓冲区可以以多种方式构建。 Method 1 以下是创建10个八位字节的无启动缓

  • 我试图构建一些Java代码来调用用VC++编写的DLL中的一些网络功能。导出的函数包括(来自.h文件) 然后按以下方式调用它 但是执行对CsilGetData的调用会给出 线程“main”java.lang.error:在com.sun.jna.Native.invokeint(本机方法)在com.sun.jna.function.invoke(function.java:371)在com.sun

  • 问题内容: 在Python中,您可以将StringIO用作字符数据的文件状缓冲区。内存映射文件基本上对二进制数据执行类似的操作,但是它需要一个用作基础的文件。Python是否有一个用于二进制数据且仅是内存的文件对象,相当于Java的ByteArrayOutputStream? 我的用例是我想在内存中创建一个ZIP文件,而ZipFile需要一个类似文件的对象。 问题答案: 您可能正在寻找io.Byt

  • 我有一个二进制数据缓冲区,我想存储在协议缓冲区中。 在留档(https://developers.google.com/protocol-buffers/docs/proto#scalar)中,它说类型等价于C中的。我无法相信这一点,所以我不得不尝试它,是的,这似乎是这样... 本协议: 给出一个包含以下内容的消息定义: 公共setter/getter API如下所示: 当然,这不是在消息中存储二