在C语言的网络编程中,很多数据结构都有些习惯的用法,这里就记录一下一些常见的用法,备忘。
下面是在OSPF协议代码中定义的一个共用体,并且使用到了段域。而且,每一个段域的定义都使用了_pack这个修饰词。
#if (_BYTE_ORDER == _LITTLE_ENDIAN )
typedef _struct
{
BIT_FIELD (enum, BOOLEAN) transit:1; /* This is a transit area */
BIT_FIELD (enum, BOOLEAN) virtual_up:1; /* One or more virtual links in this area are up */
BIT_FIELD (enum, BOOLEAN) stub:1; /* This is a area (no external routes) */
BIT_FIELD (enum, BOOLEAN) nssa:1; /* This is a not so stubby area */
BIT_FIELD (enum, BOOLEAN) stub_default:1; /* Inject default into this stub area */
BIT_FIELD (enum,BOOLEAN) not_used:3;
} _pack OSPF_AREA_FLAGS;
#else /* _BYTE_ORDER == _BIG_ENDIAN */
typedef _struct OSPF_AREA_FLAGS
{
BIT_FIELD (enum,BOOLEAN) not_used:3;
BIT_FIELD (enum, BOOLEAN) stub_default:1; /* Inject default into this stub area */
BIT_FIELD (enum, BOOLEAN) nssa:1; /* This is a not so stubby area */
BIT_FIELD (enum, BOOLEAN) stub:1; /* This is a area (no external routes) */
BIT_FIELD (enum, BOOLEAN) virtual_up:1; /* One or more virtual links in this area are up */
BIT_FIELD (enum, BOOLEAN) transit:1; /* This is a transit area */
} _pack OSPF_AREA_FLAGS;
#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
typedef _union UNION_OSPF_AREA_FLAGS
{
OSPF_AREA_FLAGS _bit;
BYTE _byte;
} _pack UNION_OSPF_AREA_FLAGS;
下面是定义的枚举类型在结构体中的应用。
typedef struct OSPF_AREA_ENTRY
{
struct OSPF_AREA_ENTRY *sptr_forward_link;
struct OSPF_AREA_ENTRY *sptr_backward_link;
......
UNION_OSPF_AREA_FLAGS flags; /* Various state bits */
......
} OSPF_AREA_ENTRY;
OSPF_AREA_ENTRY *pOspfArea;
pOspfArea->flags._bit.nssa = TRUE;
_pack的用法
在上面的段域和共用体的定义中,使用到了_pack这个关键字。_pack的定义如下所示:
#if defined (__VXWORKS__)
#if !defined (WIN32)
#define _pack __attribute__ ((packed)) /* gnu cc pack attribute */
#endif
#else
#define _pack
#endif
_pack用于是否字节对齐,如何字节对齐。在这里,就是默认使用1个字节的对齐方式,这样提高代码的可移植性。
共用体和段域
在结构体OSPF_AREA_ENTRY中,使用一个字节的空间实现变量flag的枚举。这里就是巧妙的使用了共用体的枚举类型实现。