Вспоминаем о выравнивании (не говорю о том, что числовые поля нужно привести в сетевой вид, дабы на удаленной стороне была уже произведена корректная распаковка данных: man 3 htons/ntohs, man 3 htonl/htohl, man 3 endian), чешем репу - а если приёмная сторона использует другое выравнивание, нежели у нас при сборке бинарника?((по рабоче-крестьянски: на типичной 32бит машине все переменные выравнены по 32битной длинне))
Вижу варианты:
- пихать все в char-буффер - некрасиво
- поэлементно отправлять - неудобно и некрасиво
- использовать #pragma pack() - удобно, красиво, но не супер переносимо
- использовать систему атрибутов GCC - не переносимо
Посмотрим на использование #pragma pack(), конкретно посмотреть подробности на официальной странице: http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html
При объявлении структуры, которая будет гоняться по сети рекомендуется отключить выравнивание:
#pragma pack(push,1)
....
#pragma pack(pop)
Простой пример:
#include <stdio.h>
#pragma pack(push,1)
struct test_packed {
char ch;
long data;
};
#pragma pack(pop)
struct test_unpacked {
char ch;
long data;
};
int main()
{
printf("Packed size: %d, Unpacked size: %d<br/>n",
sizeof(struct test_packed),
sizeof(struct test_unpacked));
return 0;
}
Компилируем и выполняем:
$ gcc -o main main.c && ./main
Packed size: 5, Unpacked size: 8
Всё наглядно :)
Не рекомендуется использовать для обычной работы: в размерах выигрыша почти не получится, а в скорости доступа проиграете.
UPD: тут 864110|#864110 подкинули ещё ссылку: http://www.leonerd.org.uk/code/libpack/
PS по слухам появилось в 2.95.2 или около того.