Pla*_*Max 5 c++ arrays struct arp
我正在编写一个用于创建,发送,接收和解释ARP数据包的程序.我有一个表示ARP头的结构,如下所示:
struct ArpHeader
{
unsigned short hardwareType;
unsigned short protocolType;
unsigned char hardwareAddressLength;
unsigned char protocolAddressLength;
unsigned short operationCode;
unsigned char senderHardwareAddress[6];
unsigned char senderProtocolAddress[4];
unsigned char targetHardwareAddress[6];
unsigned char targetProtocolAddress[4];
};
Run Code Online (Sandbox Code Playgroud)
这仅适用于长度为6的硬件地址和长度为4的协议地址.地址长度也在标题中给出,因此要正确,结构必须如下所示:
struct ArpHeader
{
unsigned short hardwareType;
unsigned short protocolType;
unsigned char hardwareAddressLength;
unsigned char protocolAddressLength;
unsigned short operationCode;
unsigned char senderHardwareAddress[hardwareAddressLength];
unsigned char senderProtocolAddress[protocolAddressLength];
unsigned char targetHardwareAddress[hardwareAddressLength];
unsigned char targetProtocolAddress[protocolAddressLength];
};
Run Code Online (Sandbox Code Playgroud)
这显然不起作用,因为在编译时不知道地址长度.模板结构也不是一个选项,因为我想填充结构的值,然后将它从(ArpHeader*)转换为(char*)以获得可以在网络上发送的字节数组或转换从(char*)到(ArpHeader*)的接收字节数组,以便解释它.
一种解决方案是创建一个包含所有头字段作为成员变量的类,一个创建表示可以在网络上发送的ARP头的字节数组的函数,以及一个只占用一个字节数组(在网络上接收)的构造函数并通过读取所有头字段并将其写入成员变量来解释它.这不是一个很好的解决方案,因为它需要更多的代码.
相反,例如UDP报头的类似结构是简单的,因为所有报头字段具有已知的恒定大小.我用
#pragma pack(push, 1)
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)
围绕结构声明,以便我可以实际进行简单的C样式转换,以获得在网络上发送的字节数组.
我可以在这里使用哪种解决方案接近结构,或者至少不需要比结构更多的代码?我知道结构中的最后一个字段(如果它是一个数组)不需要特定的编译时大小,我可以使用类似的东西来解决我的问题吗?只是将这4个数组的大小留空将编译,但我不知道它将如何实际起作用.从逻辑上讲,它不起作用,因为如果第一个数组的大小未知,编译器将不知道第二个数组的起始位置.
您需要一个相当低级别的东西,一个ARP数据包,并且您正在尝试找到一种正确定义数据结构的方法,以便您可以将blob转换为该结构.相反,您可以在blob上使用接口.
struct ArpHeader {
mutable std::vector<uint8_t> buf_;
template <typename T>
struct ref {
uint8_t * const p_;
ref (uint8_t *p) : p_(p) {}
operator T () const { T t; memcpy(&t, p_, sizeof(t)); return t; }
T operator = (T t) const { memcpy(p_, &t, sizeof(t)); return t; }
};
template <typename T>
ref<T> get (size_t offset) const {
if (offset + sizeof(T) > buf_.size()) throw SOMETHING;
return ref<T>(&buf_[0] + offset);
}
ref<uint16_t> hwType() const { return get<uint16_t>(0); }
ref<uint16_t> protType () const { return get<uint16_t>(2); }
ref<uint8_t> hwAddrLen () const { return get<uint8_t>(4); }
ref<uint8_t> protAddrLen () const { return get<uint8_t>(5); }
ref<uint16_t> opCode () const { return get<uint16_t>(6); }
uint8_t *senderHwAddr () const { return &buf_[0] + 8; }
uint8_t *senderProtAddr () const { return senderHwAddr() + hwAddrLen(); }
uint8_t *targetHwAddr () const { return senderProtAddr() + protAddrLen(); }
uint8_t *targetProtAddr () const { return targetHwAddr() + hwAddrLen(); }
};
Run Code Online (Sandbox Code Playgroud)
如果您需要const正确性,则删除mutable,创建一个const_ref,并将访问者复制到非const版本中,并使const版本返回const_ref和const uint8_t *.
| 归档时间: |
|
| 查看次数: |
2448 次 |
| 最近记录: |