我正在编写一个用于创建,发送,接收和解释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个数组的大小留空将编译,但我不知道它将如何实际起作用.从逻辑上讲,它不起作用,因为如果第一个数组的大小未知,编译器将不知道第二个数组的起始位置.