在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的枚举。这里就是巧妙的使用了共用体的枚举类型实现。