在C ++ 11中反序列化DNS数据包对象

时间:2015-09-04 09:20:45

标签: c++ c++11 serialization dns

我有一个类似于此的DNS数据包类(我只粘贴它的一部分):

class DNSPacket {

public:
    struct DNSHeader {
        unsigned int ID :16; 
        unsigned int QR :1;  
        unsigned int OPCODE :4;  
        unsigned int AA :1;   
        unsigned int TC :1;  
        unsigned int RD :1;    
        unsigned int RA :1;   
        unsigned int Z :3;   

        unsigned int RCODE :4;
        unsigned int QDCOUNT :16;
        unsigned int ANCOUNT :16;
        unsigned int NSCOUNT :16;
        unsigned int ARCOUNT :16;
    };

private:
    DNSHeader header;
    std::vector<DNSQuestion> questions;
    std::vector<DNSAnswer> answers;
    std::vector<DNSAnswer> nameservers; // TODO: DNSAnswer?
    std::vector<DNSAnswer> add_records; // TODO: DNSAnswer?
}

char数组反序列化为此对象的正确方法是什么?我有的选项是:重载>>运算符,添加一个单独的类来反序列化它,以便在字节之后读取和反序列化数据读取字节并使用reinterpret_cast()

我想在C ++ 11中创建一个快速,现代的实现。我应该选择哪种方式?另外,我应该如何反序列化位域 - 我应该坚持按位操作吗?

1 个答案:

答案 0 :(得分:1)

我这样做的方法是将字2(位16到31)视为单个无符号16位整数(例如uint16_t),并通过逐位AND和SHIFT简单地获取这些位操作。所有其他单词可以以相同的方式读取,但按原样使用或多或少(在从网络字节顺序转换为主机字节顺序之后)。

要将单词X字作为uint16_t,你必须进行一些演员:

uint16_t wordX = *reinterpret_cast<uint16_t*>(&your_array[X]);

注意,对于第二个字,由于它们实际上只是位,它们按指定的顺序排列,因此不会对它们进行字节顺序转换。