为什么8位字段具有字节序?

时间:2009-05-14 15:35:06

标签: c networking interop system endianness

请参阅/netinet/tcp.h中TCP标头的定义:

struct tcphdr
  {
    u_int16_t th_sport;         /* source port */
    u_int16_t th_dport;         /* destination port */
    tcp_seq th_seq;             /* sequence number */
    tcp_seq th_ack;             /* acknowledgement number */
#  if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t th_x2:4;           /* (unused) */
    u_int8_t th_off:4;          /* data offset */
#  endif
#  if __BYTE_ORDER == __BIG_ENDIAN
    u_int8_t th_off:4;          /* data offset */
    u_int8_t th_x2:4;           /* (unused) */
#  endif
    u_int8_t th_flags;
#  define TH_FIN        0x01
#  define TH_SYN        0x02
#  define TH_RST        0x04
#  define TH_PUSH       0x08
#  define TH_ACK        0x10
#  define TH_URG        0x20
    u_int16_t th_win;           /* window */
    u_int16_t th_sum;           /* checksum */
    u_int16_t th_urp;           /* urgent pointer */
};

为什么8位字段的字节顺序不同?我认为只有16位和32位字段与字节顺序相关,你可以分别用ntoh和ntohl在字节之间进行转换。处理8位内容的功能是什么?如果没有,似乎在小端机器上使用此标头的TCP将无法在大端机器上使用TCP。

6 个答案:

答案 0 :(得分:21)

有两种订单。一个是字节顺序,一个是位域顺序。 关于C语言中的位域顺序没有标准顺序。这取决于编译器。通常,位域的顺序在大端和小端之间反转。

答案 1 :(得分:11)

这是编译器相关且不可移植的。如何对位字段进行排序依赖于实现,这里使用8位字段和移位/掩码来获得子字段要好得多。

答案 2 :(得分:3)

可能在本机中,endianess也指位顺序和字节顺序。 This wikipedia article提到有时候这种情况。

答案 3 :(得分:1)

我的理解是位排序和字节顺序通常是两个不同的东西。具有位字段的结构通常不能跨编译器/体系结构移植。有时ifdefs可用于支持不同的位排序。在这种情况下,字节顺序实际上是无关紧要的,它应该是关于位排序的ifdef。在某些情况下,某些结束具有某种位序的假设可能是正确的。

答案 4 :(得分:0)

我对该注释的解读是,两个单字节字段一起被解释为一个双字节值(或者 - 似乎是一个字节未使用)。它们声明了两个单字节值,而不是声明一个双字节值,而是根据字节顺序反转声明的顺序。

答案 5 :(得分:0)

可能有助于知道这是代码仅在“#ifdef __FAVOR_BSD”时运行。它来自/usr/include/netinet/tcp.h

# ifdef __FAVOR_BSD
typedef u_int32_t tcp_seq;
/*
 * TCP header.
 * Per RFC 793, September, 1981.
 */
struct tcphdr