我用booost系列化这种方式:
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
总的来说,这是不可能预测的。这取决于(很多)上的归档格式。但随着物体完全跟踪子图可能被省略,并与动态类型的信息可以被添加了大量的数据。
如果你能负担得起从头缓冲区的序列化数据,你可以序列化到一个缓冲区,然后再发送有效载荷之前发送大小(现在你知道它)。
将有开销
这里有一些答案,让你了解这些的调整点的详细信息:
如果您的所有数据是POD,很容易预测的大小。
如果您在同一台机器上共享IPC,并且你已经在使用循环缓冲器,考虑将循环缓冲到共享内存中。
我有很多答案(搜索managed_shared_memory
或managed_mapped_file
)有这方面的例子。
一个具体的例子,重点是无锁单生产者/单消费者场景是在这里:Shared-memory IPC synchronization (lock-free)
即使你选择/需要流消息(例如通过网络),你仍然可以使用例如Managed External Buffers。特此你避免需要做任何系列化甚至无需将所有数据POD。 (诀窍是,在内部,offset_ptr<>
来代替原始指针,使得相对于所有的参考文献)。
创建您自己的流类并重写xsputn
方法。
class counter_streambuf : public std::streambuf {
public:
using std::streambuf::streambuf;
size_t size() const { return m_size; }
protected:
std::streamsize xsputn(const char_type* __s, std::streamsize __n) override
{ this->m_size += __n; return __n; }
private:
size_t m_size = 0;
};
用法:
Header H(__Magic, SSP_T_REQUEST, 98, 72, 42, Date(), SSP_C_NONE);
counter_streambuf csb;
boost::archive::binary_oarchive oa(csb, boost::archive::no_header);
oa & H;
cout<<"Size: "<<csb.size();