在c中将64位int从主机转换为网络顺序,我只得到零

时间:2014-07-01 16:01:09

标签: c 64-bit endianness

对于家庭作业问题,我需要将64位int从主机转换为C中的网络顺序.64位int存储在一个联合中(如下面编码)并由id_generator随机生成(见下文)。我正在尝试使用nw_order函数转换它的顺序,当我打印它来控制顺序时,它们只是零。 例如,我得到这个输出:

主机订单:6D 5F E5 31

净订单:0 0 0 0

那么,我在这里缺少什么?

union u
{
    uint64_t u64;
    uint32_t u32[2];

};

nw_order函数接受两个参数,并将第一个参数的转换顺序分配给第二个参数:

void nw_order(const union u *host, union u *net)
{

   net -> u32[0] = htonl(net->u32[1]);
   net -> u32[1] = htonl(net->u32[0]);

}

我不知道它是否会导致问题,但随机生成器功能是:

uint64_t id_generator()
{
 union u clientid;

 if(sizeof(long) > 7)
  clientid.u64 = (uint64_t)random();
 else
 {
   clientid.u32[0] = (uint32_t)random();
   clientid.u32[1] = (uint32_t)random();
 }

 return clientid.u64;

}

转换前后打印的主要功能:

int main()
{

   union u client_id;
   union u net;
   unsigned char* p;


   srandom(time(NULL));

   client_id.u64 = (uint64_t) id_generator();

   p = (unsigned char *) &client_id.u64;

   printf("host order: %X %X %X %X\n",*p,*(p+1),*(p+2),*(p+3)); /* host ord*/

   nw_order(&client_id, &net);

   p = (unsigned char *) &net.u64;

   printf("net order: %X %X %X %X\n",*p,*(p+1),*(p+2),*(p+3)); /* network ord*/


   return 0;
} 

1 个答案:

答案 0 :(得分:3)

void nw_order(const union u *host, union u *net)
{
   net -> u32[0] = htonl(net->u32[1]);
   net -> u32[1] = htonl(net->u32[0]);
}

您只使用指向net的指针:

这将低4字节设置为字节反转高4字节,将高4字节设置为2字节反转高4字节< =>他们以前的内容 不是你想要的,对吗?

无论如何,最好这样做:

uint64_t nw_order(const uint64_t in) {
    unsigned char out[8] = {in>>56,in>>48,in>>40,in>>32,in>>24,in>>16,in>>8,in};
    return *(uint64_t*)out;
}

这有两个好处:

  • 也适用于big-endian(你可能不在乎,如果你只是在x86上)
  • 不要不必要地使用指针。

另请注意,random()仅返回int,并且不使用完整范围:请检查RAND_MAX。无论如何,除了快速的笑话程序之外,这个功能并不具备可靠的质量。