C и выравнивание памяти для двоичного протокола - PullRequest
4 голосов
/ 07 сентября 2010

Я буду использовать этот код в качестве примера:

typedef struct __attribute__((aligned(XXX),packed))
{
   uint16_t type;
   uint32_t id_index;
} a_msg;

void write_func(){
   a_mesg mymsg
   mymsg.type = htons(1);
   mymsg.id_index = htonl(5);
   write(sock_fd, &mymsg, sizeof(a_mesg));
}

void read_func(){
   a_mesg mymsg
   read(sock_fd, &mymsg, sizeof(a_mesg));
   mymsg.type = ntohs(mymsg.type);
   mymsg.id_index = ntohl(mymsg.id_index);     
}

Примечание: sock_fd - это сокет TCP.Это немного сжатый пример, и он, возможно, не сработает, но я думаю, вы видите, что я пытаюсь привести в качестве примера (программа, которая взаимодействует по двоичному протоколу).

Если приложение будет работать только на двух 32-битных компьютерах, которые связываются друг с другом через приложение, выравнивание (выровненное (XXX)), естественно, будет установлено равным 4. Если мы установим связь между 32-битной и 64-битной машинами, каким будет выравнивание?

  1. Должно ли XXX быть 4 на 32- и 64-разрядных компьютерах?
  2. Должно ли XXX быть 8 на 32- и 64-разрядных компьютерах?
  3. Должно ли ХХХ быть 8 на 64-х машинах и 4 на 32-битных машинах?
  4. ХХХ имеет другое значение.

Моя ставка на альтернативу 2.

Ответы [ 3 ]

3 голосов
/ 07 сентября 2010

Я бы использовал

#pragma pack 1

для структур.Это не дает заполнения, что означает меньший чистый трафик (меньше байтов для отправки).Легкое литье.

Пример:

struct S1 {
   char c1;  // Offset 0, 3 bytes padding
   int i;    // Offset 4, no padding
   char c2;  // Offset 8, 3 bytes padding
};  // sizeof(S1)==12, alignment 4

#pragma pack 1

struct S2 {
   char c1;  // Offset 0, no padding
   int i;    // Offset 1, no padding
   char c2;  // Offset 5, no padding
};  // sizeof(S2)==6, alignment 1
0 голосов
/ 03 марта 2011

я делаю

__attribute__((aligned(1),packed))

это работает =)

0 голосов
/ 07 сентября 2010

Я бы всегда использовал упакованные структуры для любого протокола связи. Меньше возможностей для путаницы, нет ненужных накладных расходов, нет сложного заброса для устранения заполнения на другом конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...