【问题标题】:Why does an 8-bit field have endianness?为什么 8 位字段具有字节顺序?
【发布时间】:2010-10-26 05:33:21
【问题描述】:

见/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 位字段与字节顺序有关,您可以分别使用 ntohs 和 ntohl 在字节序之间进行转换。处理 8 位事物的功能是什么?如果没有,那么在小端机器上使用此标头的 TCP 似乎不适用于大端机器上的 TCP。

【问题讨论】:

  • 真是奇怪,你是在哪个系统上找到这个头文件的?
  • debian linux。如果 __USE_BSD 为 #defined,则包含此版本。

标签: c networking interop system endianness


【解决方案1】:

知道这是代码仅在“# 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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      这是依赖于编译器且不可移植的。位字段的排序方式取决于实现,这里最好使用 8 位字段和移位/掩码来获取子字段。

      【讨论】:

      • 对我来说听起来是一个更好的计划。
      【解决方案4】:

      在这台机器中,字节序可能也指位顺序和字节顺序。 This wikipedia article 提到有时会出现这种情况。

      【讨论】:

      • 本题与位序无关。
      【解决方案5】:

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

      【讨论】:

      • 这似乎是正确的答案,我模糊记得以前听过它,但我不能在没有引用的情况下凭良心投票...你能提供一个吗?
      • 这是唯一对我有意义的答案
      • 那不应该是__BIG_ENDIAN_BITFIELD/__LITTLE_ENDIAN_BITFIELD吗?或者他们隐含地假设字节顺序和位域顺序之间的字节顺序保持不变?
      【解决方案6】:

      我对评论的解读是,这两个单字节字段一起被解释为一个双字节值(或者曾经——似乎无论如何都没有使用一个字节)。它们不是声明一个两字节值,而是声明两个一字节值,但根据字节序颠倒声明顺序。

      【讨论】:

      猜你喜欢
      • 2018-05-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 1970-01-01
      • 2019-07-31
      相关资源
      最近更新 更多