数据大小端64位字节相互转换

在linux内核中有htonll()这个函数来进行网络大小端字节转换的功能,但是在Libc中没提供此函数,所以必须自己利用已用的函数进行封装。

大小端与数据存放顺序

C语言中,大于一个字节的数据类型在内存中表示时,不同CPU有不同的存放顺序,分为大端序和小端序。大端序即高字节存放在低地址,小端序相反。

  • 例: int x = 0x12345678, &x == 0x100,其大小端表示如下:
    在这里插入图片描述

字节序转换

通常在网络间传输数据时,因为是在不同机器上进行交互,所以需要先将数据转换成网络字节序,再发往对端。网络字节序是TCP/IP中定义的数据格式,与具体CPU、OS无关,采用大端表示。

常用的转换函数有:
#include <arpa/inet.h>

uint16_t htons(uint16_t hostshort); /* host to network short */

uint32_t htonl(uint32_t hostlong); /* host to networklong */

uint16_tntohs(uint16_tnetshort); /*network to host short */

uint32_t ntohs(uint32_t netlong); /*networkto host short */

现在如果需要将64位的long long类型数据从本机(小端)转换为网络字节序,就没有现成的API可用了。可以通过下面两种方法进行转换:

  1. 使用移位
unsigned long long u64_host, u64_net;
unsigned int  u32_host_h, u32_host_l;
u32_host_l = u64_host & 0xffffffff;
u32_host_h = (u64_host >> 32) & 0xffffffff;
 
u64_net = htonl(u32_host_l);
u64_net = ( u64_net << 32 ) | htonl(u32_host_h);
 
printf("htonll : %016llx\n", u64_net);

test >>>

in: 0x0102030405060708

out: 0x0807060504030201

  1. 使用联合体

根据联合体的特性:联合体中所有成员引用的是内存中相同的位置,其长度为最长成员的长度

typedef struct {
	unsigned int u32_h;
	unsigned int u32_l;
}Int64_t;
 
typedef union {
	unsigned long long u64;
	Int64_t st64;
}Convert64_t;
 
unsigned long long u64_host, u64_net;
Convert64_t box_in, box_out;
 
box_in.u64 = u64_host;
box_out.st64.u32_h = htonl(box_in.st64.u32_l);
box_out.st64.u32_l = htonl(box_in.st64.u32_h);
u64_net = box_out.u64;
 
printf("htonll : %016llx\n", u64_net);

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值