C和二进制协议的内存对齐

时间:2010-09-07 07:57:36

标签: c gcc unix

我将使用此代码作为示例:

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. 32位和64位计算机上的XXX应该是4吗?
  2. 32位和64位计算机上的XXX应该是8吗?
  3. 在64台机器上XXX应该是8,在32位机器上是4吗?
  4. XXX具有其他一些价值。
  5. 我打赌替代方案2。

3 个答案:

答案 0 :(得分:3)

我会用

#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

答案 1 :(得分:0)

我总是使用压缩结构来处理任何通信协议。混淆的范围较小,没有不必要的开销,没有困难的铸造来消除另一端的填充。

答案 2 :(得分:0)

我在做

__attribute__((aligned(1),packed))

它起作用=)