c++中的数据包序列化

Packet serialization in C++

本文关键字:序列化 数据包 c++      更新时间:2023-10-16

我有一个项目,它对几种不同类型(Packet1, Packet2…)进行数据包序列化。它们都扩展了一个PacketHeader类并进行了自己的序列化

这种方法看起来非常混乱且容易出错,特别是当字段数量增加时。

是否有更干净和更多的OOP &c++的序列化方式(没有第三方库)?

class PacketHeader {
    uint8_t type;
    uint32_t id;
    uint32_t seqNum;
    virtual void serialize(uint8_t *buf, size_t size) {
        int offset = 0;
        PacketHeader n;
        n.type = type;
        n.id = htonl(id);
        n.seqNum = htonl(seqNum);
        memcpy(buf + offset, &(n.type), sizeof(n.type));
        offset += sizeof(n.type);
        memcpy(buf + offset, &(n.id), sizeof(n.id));
        offset += sizeof(n.id);
        memcpy(buf + offset, &n.seqNum, sizeof(n.seqNum));
        offset += sizeof(n.seqNum);
    }
}
class Packet1 : public PacketHeader {
    uint32_t payload;
    virtual void serialize(uint8_t *buf, size_t size) {
        int offset = PacketHeader::size();
        PacketHeader::serialize(buf, size);
        memcpy(buf + offset, &n.payload, sizeof(n.payload));
        offset += sizeof(n.payload);
    }
}

对具有数据成员的结构和类进行本机序列化需要向序列化器提供每个成员的偏移量、大小和类型信息。这就是"凌乱"的根源,无论你的设计多么优雅,你都无法避免。

有一些帮助库可以提供一些结构,但它们通常只是语法糖果,并且随着消息类型数量的增长仍然很难维护。

相反,我建议查看提供字典(键/值数据对象)的系统,而不是使用本地c++结构/类数据成员。有些使用标准的序列化格式,如JSON。JSONCPP是一个非常受欢迎的包,它可以完成以下工作:http://jsoncpp.sourceforge.net/

大多数情况下,它们提供的优势是软件系统可以随着增长而更好地扩展,并且不会成为指数级维护问题。

如果需要二进制序列化,请查看BSON, MessagePack, Google Protocol Buffers和Apache Thrift。