我不太明白在常规数组上使用 streambuf 的优势。
让我解释一下我的问题。我有一个网络连接,它使用 Rijndael 128 ECB + 一些简单的密码加密来加密短于 16 字节的剩余数据。数据包的结构为 length_of_whole_packet+operationcode+data。我必须实际从流缓冲中复制所有数据,以便我可以应用解密算法?为什么要复制我已有的数据?

我在发送数据时遇到了同样的问题。当处于安全模式时,数据包结构为 length_of_whole_packet+crc+data,其中 crc 和数据被加密。我可以做一些像 MakePacket(HEADER, FORMAT, ...) 这样的怪物来分配数组,格式化数据包,添加 crc 并加密它,但我想避免 vararg 函数。我不能使用结构,因为数据包具有动态长度,因为其中可能有数组或字符串。如果我使用 MakePacket(unsigned char opcode, &streambuf sb) 那么 crc 会再次出现问题 -> 必须制作一个拷贝来加密它。

我应该使用 vararg monstrosity 发送使用常规数组作为缓冲区并结合 unsigned char pbyRecvBuffer[BUFFERMAXLEN] 进行接收吗?

我不太确定如何通过避免数据拷贝来设计这种通信。

谢谢你的回答。

最佳答案

使用 streambuf 时,通常可以通过使用对迭代器进行操作的算法(例如 std::istreambuf_iterator boost::asio::buffers_iterator )来最小化数据的复制,而不是将数据从 streambuf 复制到另一个数据结构中。

对于类似流的应用协议(protocol), boost::asio::streambuf 通常优于 boost::asio::buffer() 兼容类型,例如原始数组。例如,考虑 HTTP ,其中使用分隔符来标识可变长度 header 和正文之间的边界。更高级别的 read_until() 操作提供了一种读取协议(protocol)的优雅方式,因为 Boost.Asio 将处理内存分配,检测分隔符,并在到达消息边界后调用完成处理程序。如果应用程序使用原始数组,则需要读取块并将每个碎片块复制到聚合内存缓冲区中,直到识别出适当的分隔符。

如果应用程序可以确定要读取的确切字节数,那么可能值得考虑对固定长度部分使用 boost::array,对可变长度部分使用 std::vector。例如,一个应用程序协议(protocol)具有:

  • 固定长度主体可以读入 boost::array
  • 固定长度头包含足够的信息来确定以下可变长度主体的长度,可以使用 std::vector 读取固定长度头,一旦确定主体长度,调整 vector 的大小,然后读取主体。

  • 在问题的上下文中,如果 length_of_whole_packet 是固定长度,应用程序可以将其读入 std::vector ,根据确定的正文长度调整 vector 的大小,然后将剩余数据读入 vector 。然后,解密算法可以直接对 vector 进行操作,并使用输出迭代器(例如 std::back_insert_iterator )和辅助输出缓冲区(如果算法无法就地完成)。这同样适用于加密要写入的数据。

    关于c++ - asio::streambuf 相对于原始数组的优势,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24328522/

    10-15 06:24