我正在尝试构建一个简单的自定义应用层协议,本质上带有时间戳以及一些其他有用的信息,以便在不同的 Linux 系统之间执行少量网络测量。
就 Linux 系统而言,在我最初的想法中,实现应该尽可能地在不同平台(x86、ARM、...)之间移植。
为了管理标题,我创建了这个结构:
struct myhdr {
__u8 reserved; // 1 byte
__u8 ctrl; // 1 byte
__u16 id; // 2 bytes
__u16 seq; // 2 bytes
__u16 len; // 2 bytes
struct timeval sendtime; // 8 or 16 bytes
};
之后,一些有效载荷数据可能存在也可能不存在(如果 len=0)。由于这些数据必须通过网络发送,如果我没记错的话,我需要要打包的结构,没有任何对齐填充。
我的疑问实际上是这是否可以被认为是已经打包的,主要是由于存在struct timeval
, 来携带时间戳。
在 32 位系统下,struct timeval
应该是 8 个字节。在 64 位系统下,它应该是 16 字节(刚刚通过打印测试过sizeof(struct timeval)
)。
在 32 位系统下,假设它已经打包是否安全,因为 1+1+2+2+2 字节 = 8 字节,即 的大小sendtime
?或者在任何情况下都会添加一个填充,以便将每个字段与最后一个字段对齐,哪个是最大的?
那么在最后一个字段是 16 字节的 64 位系统中会发生什么?我认为在任何情况下,结构都不会再“被布局打包”了(这是正确的吗?)。
在为不同平台编译代码时,添加是否__attribute__((packed))
足够且始终有必要确保结构被打包?有更好的解决方案吗?