我以这种方式使用 boost 序列化:
Header H(__Magic, SSP_T_REQUEST, 98, 72, 42, Date(), SSP_C_NONE);
Header Z;
std::cout << H << std::endl;
std::cout << std::endl;
char serial_str[4096];
std::memset(serial_str, 0, 4096);
boost::iostreams::basic_array_sink<char> inserter(serial_str, 4096);
boost::iostreams::stream<boost::iostreams::basic_array_sink<char> > s(inserter);
boost::archive::binary_oarchive oa(s);
oa & H;
s.flush();
std::cout << serial_str << std::endl;
boost::iostreams::basic_array_source<char> device(serial_str, 4096);
boost::iostreams::stream<boost::iostreams::basic_array_source<char> > s2(device);
boost::archive::binary_iarchive ia(s2);
ia >> Z;
std::cout << Z << std::endl;
它工作得很好。
尽管如此,我需要在套接字上发送这些数据包。我的问题是,我如何知道另一端我需要读取多少字节?序列化结果的大小不是恒定的,顺便说一句,它比我的结构的 sizeof 大。
如何确定对方的数据是完整的?我使用循环缓冲区但使用序列化怎么办?
Thx all
一般来说,这是不可能预测的。这在很大程度上取决于存档格式。但是,通过完全对象跟踪,子图可能会被省略,并且通过动态类型信息,可以添加大量数据。
如果您能为序列化数据提供暂存缓冲区,则可以先序列化到缓冲区,然后在发送有效负载之前发送大小(现在您知道了)。
会有开销
- 对象跟踪(通过指针/引用进行序列化)
- 动态多态性(通过(智能)指向基点的指针进行序列化)
- 版本控制(除非您对所涉及的类型禁用它)
- 存档标头(除非禁用)
- 代码转换(除非禁用)
以下是一些答案,可为您提供有关这些调整点的更多信息:
- Boost C++ 序列化开销
- Boost 序列化二进制存档给出不正确的输出
- 矢量 的 Boost 序列化
- 调整内容(boost::archive::no_codecvt、boost::archive::no_header、禁用跟踪 etc.)
如果您的所有数据都是 POD,则很容易预测其大小。
盒子外面
如果您在同一台机器上共享 IPC,并且已经在使用循环缓冲区,请考虑将循环缓冲区放入共享内存中。
我有很多答案(搜索managed_shared_memory
or managed_mapped_file
)并举例说明。
一个具体的例子,重点关注无锁的单一生产者/单一消费者场景:共享内存IPC同步(无锁)
即使您选择/需要流式传输消息(例如通过网络),您仍然可以使用例如托管外部缓冲区。这样你就可以避免需要做的事情any甚至不需要所有数据都是 POD 的序列化。 (诀窍是在内部,offset_ptr<>
使用而不是原始指针,使所有引用都是相对的)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)