我不太明白在常规数组上使用 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/