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

16

请查看/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正常工作。

确实很奇怪,你在哪个系统中找到这个头文件的? - fbonnet
Debian Linux。如果 __USE_BSD 被 #define,该版本将被包含。 - Claudiu
6个回答

22

有两种类型的排序方式。一种是字节序,另一种是位域顺序。

C 语言中没有关于位域顺序的标准顺序。它取决于编译器。通常情况下,位域的顺序在 big endian 和 little endian 之间是相反的。


1
这似乎是正确的答案,我模糊地记得之前听过这个答案,但是如果没有引用,我不能在良心上点赞...你能提供一个引用吗? - rmeador
这是唯一对我有意义的答案。 - Claudiu
应该是 __BIG_ENDIAN_BITFIELD/__LITTLE_ENDIAN_BITFIELD 吧?或者它们默认假设字节序和位域顺序之间保持一致? - Slava

11

这取决于编译器而且不可移植。位域的排列方式取决于实现,最好使用8位域并进行移位/掩码以获取子域。


对我来说,这听起来是一个更好的计划。 - Dave Cluderay

2

在这台机器上,字节序可能不仅仅指字节顺序,也包括位的顺序。 维基百科的文章提到这种情况有时会发生。


在这个问题中,与位序无关。 - kcwu

1

我的理解是位序和字节序通常是两个不同的概念。带有位域的结构体通常在编译器/架构之间不可移植。有时可以使用ifdef来支持不同的位序。在这种情况下,字节序实际上并不重要,应该是关于位序的ifdef。某些字节序具有特定位序的假设在某些情况下可能是正确的。


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

0

我对评论的理解是这两个一字节字段一起被构造成一个两字节的值(或者曾经是这样 —— 不管怎样,似乎有一个字节是未使用的)。他们不是声明一个两字节的值,而是声明两个一字节的值,根据大小端顺序颠倒声明的顺序。


不,它明显是要定义两个4位字段。请参见例如http://www.freesoft.org/CIE/Course/Section4/8.htm以获取TCP头布局。 - Lance Richardson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接