在 C++11 中反序列化 DNS 数据包对象
Deserializing a DNS packet object in C++11
我有一个 DNS 数据包 class 看起来像这样(我只粘贴了其中的一部分):
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
数组反序列化为该对象的正确方法是什么?我有的选项是:重载 >>
运算符,添加一个单独的 class 来反序列化它以逐字节读取和反序列化数据读取并使用 reinterpret_cast()
.
我想在 C++11 中创建一个快速、现代的实现。我应该选择哪种方式?另外,我应该如何反序列化位域 - 我应该坚持按位运算吗?
我的做法是将字 2(第 16 位到第 31 位)视为单个无符号 16 位整数(例如 uint16_t
),然后使用按位 AND 简单地获取这些位和 SHIFT 操作。所有其他单词都可以用相同的方式读取,但或多或少按原样使用(当然是在从网络字节顺序转换为主机字节顺序之后)。
要将单词 X 作为 uint16_t
您必须进行一些转换:
uint16_t wordX = *reinterpret_cast<uint16_t*>(&your_array[X]);
请注意,对于第二个字,由于它们实际上只是按指定顺序排列的位,因此不会对它们进行字节顺序转换。
我有一个 DNS 数据包 class 看起来像这样(我只粘贴了其中的一部分):
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
数组反序列化为该对象的正确方法是什么?我有的选项是:重载 >>
运算符,添加一个单独的 class 来反序列化它以逐字节读取和反序列化数据读取并使用 reinterpret_cast()
.
我想在 C++11 中创建一个快速、现代的实现。我应该选择哪种方式?另外,我应该如何反序列化位域 - 我应该坚持按位运算吗?
我的做法是将字 2(第 16 位到第 31 位)视为单个无符号 16 位整数(例如 uint16_t
),然后使用按位 AND 简单地获取这些位和 SHIFT 操作。所有其他单词都可以用相同的方式读取,但或多或少按原样使用(当然是在从网络字节顺序转换为主机字节顺序之后)。
要将单词 X 作为 uint16_t
您必须进行一些转换:
uint16_t wordX = *reinterpret_cast<uint16_t*>(&your_array[X]);
请注意,对于第二个字,由于它们实际上只是按指定顺序排列的位,因此不会对它们进行字节顺序转换。