Почему 8-битное поле имеет порядок байтов? - PullRequest
15 голосов
/ 14 мая 2009

См. Определение заголовка TCP в /netinet/tcp.h:

.
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 на машине с прямым порядком байтов.

Ответы [ 6 ]

21 голосов
/ 14 мая 2009

Есть два вида заказа. Один - порядок байтов, другой - порядок битовых полей. Не существует стандартного порядка порядка битовых полей на языке Си. Это зависит от компилятора. Как правило, порядок битовых полей меняется между старшим и младшим порядковым номером.

11 голосов
/ 14 мая 2009

Это зависит от компилятора и не переносимо. Как упорядочены битовые поля, зависит от реализации, здесь было бы гораздо лучше использовать 8-битное поле и shift / mask для получения подполей.

3 голосов
/ 14 мая 2009

Возможно, что в этой машине порядковый номер также относится к порядку битов и порядку байтов. В этой статье Википедии упоминается, что это иногда так.

1 голос
/ 15 мая 2009

Насколько я понимаю, порядок следования битов и порядковый номер, как правило, две разные вещи. Структуры с битовыми полями обычно не переносимы между компиляторами / архитектурами. Иногда ifdefs может использоваться для поддержки разных порядков битов. В этом случае порядковый номер действительно не имеет значения, и это должно быть ifdef относительно порядка следования битов. Предположение, что некоторые последовательности имеют определенный битовый порядок, может быть верным в некоторых случаях.

0 голосов
/ 28 февраля 2011

Может быть полезно знать, что этот код запускается только если "# 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 голосов
/ 14 мая 2009

Мое чтение комментария состоит в том, что два однобайтовых поля вместе интерпретируются как двухбайтовое значение (или были - кажется, что один байт в любом случае не используется). Вместо того, чтобы объявлять одно двухбайтовое значение, они объявляют два однобайтовых значения, но обращают порядок объявления в зависимости от endian-ness.

...