位域、 packed 属性与跨字节序二进制协议序列化
结合 __attribute__((packed)) 和位域处理网络协议头部,并解决大小端转换的移植性问题。 · 难度:入门 · +10XP
位域、 packed 属性与跨字节序二进制协议序列化
普通教程会介绍位域语法,但在实际网络协议(如 TCP/IP 头部)中,结构体需要紧密排列且考虑字节序。本教程讲解 GCC 的 packed 属性如何消除对齐填充,以及位域在不同编译器下的内存布局差异。你将实现一个 IPv4 头部解析器,手动进行字节序转换,确保代码在 x86 和 ARM 上行为一致。
struct __attribute__((packed)) ip_header {
uint8_t ver_ihl; // 4位版本 + 4位头部长度
uint8_t dscp_ecn;
uint16_t total_length;
uint16_t identification;
uint16_t flags_fragment;
uint8_t ttl;
uint8_t protocol;
uint16_t checksum;
uint32_t src_addr;
uint32_t dst_addr;
};
// 访问位域需要小心:ver_ihl 的低4位是版本,高4位是IHL
#define IP_VERSION(ver_ihl) ((ver_ihl) >> 4)
#define IP_IHL(ver_ihl) ((ver_ihl) & 0x0F)