4

我不太了解使用 streambuf 优于常规数组的优势。让我解释一下我的问题。我有一个网络连接,它使用 Rijndael 128 ECB + 一些简单的密码来加密小于 16 字节的剩余数据。数据包的结构为length_of_whole_packet+操作码+数据。我必须实际复制streambuf中的所有数据才能应用解密算法?为什么要再复制一份我已经拥有的数据?

我在发送数据时遇到了同样的问题。在安全模式下,数据包结构为 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] 进行接收吗?

我不确定如何设计这种通信以避免数据副本。

谢谢你的回答。

4

1 回答 1

3

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

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

如果应用程序可以确定要读取的确切字节数,那么可能值得考虑将其boost::array用于固定长度部分和std::vector可变长度部分。例如,具有以下内容的应用程序协议:

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

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

于 2014-06-23T03:17:06.447 回答