字节序学习

字节序是指当一个数据的长度超过一个字节时的存储顺序。
比如一个int型的数据,所占的字节数为4,那么在存储的时候第一个字节的地址为0x00B8F9F0,这个int数据占用的四个字节的地址为0x00B8F9F0,0x00B8F9F1,0x00B8F9F2,0x00B8F9F3。但是对于a的四个字节的存储顺序,在不同的处理器上可能是不同的。

对于存储顺序,分为大端序和小端序
小端序(Little-Endian):低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
大端序(Big-Endian):高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

这里字节的低位和高位指:
比如
int a = 0x01020304;
左边的01为高位,右边的04为低位这样的顺序

而地址的高端与低端指:
比如
0x00B8F9F0,0x00B8F9F1,0x00B8F9F2,0x00B8F9F3
左边地址值小的为低端,右边地址值大的为高端

小端序:

0x040x030x020x01
0x00B8F9F00x00B8F9F10x00B8F9F20x00B8F9F3

大端序:

0x010x020x030x04
0x00B8F9F00x00B8F9F10x00B8F9F20x00B8F9F3

对于存储和传输时的字节序,分为本地序和网络序
本地序指计算机存储的时候所采用的顺序,包括大端序和小端序,网络序指网络传输时采用的字节序,由于网络传输的标准化,所以一般是采用大端序。在发送网络数据之前,需要把本地序转换为网络序,也就是我们一般调用的htonl,htons函数将本地序转换为网络序,接收数据时ntohl,ntohs将网络序转为本地序。

	int a = 0x01020304;
	
	cout << "a:" << a << endl;
	cout << "a(hex):" << hex << a << endl;
	
	int8_t* b = (int8_t*)&a;
	cout << "b[0]:" << hex << (int)*b << endl;
	cout << "&b[0]:" << hex << (void*)b << endl;
	b++;
	cout << "b[1]:" << hex << (int)*b << endl;
	cout << "&b[1]:" << hex << (void*)b << endl;
	b++;
	cout << "b[2]:" << hex << (int)*b << endl;
	cout << "&b[2]:" << hex << (void*)b << endl;
	b++;
	cout << "b[3]:" << hex << (int)*b << endl;
	cout << "&b[3]:" << hex << (void*)b << endl;

	a = htonl(a);
	cout << "\nafter htonl\na:" << a << endl;
	cout << "a(hex):" << hex << a << endl;
	int8_t* c = (int8_t*)&a;
	cout << "c[0]:" << hex << (int)*c << endl;
	cout << "&c[0]:" << hex << (void*)c << endl;
	c++;
	cout << "c[1]:" << hex << (int)*c << endl;
	cout << "&c[1]:" << hex << (void*)c << endl;
	c++;
	cout << "c[2]:" << hex << (int)*c << endl;
	cout << "&c[2]:" << hex << (void*)c << endl;
	c++;
	cout << "c[3]:" << hex << (int)*c << endl;
	cout << "&c[3]:" << hex << (void*)c << endl;

输出如下:

a:16909060
a(hex):1020304
b[0]:4
&b[0]:00FEFB00
b[1]:3
&b[1]:00FEFB01
b[2]:2
&b[2]:00FEFB02
b[3]:1
&b[3]:00FEFB03

after htonl
a:4030201
a(hex):4030201
c[0]:1
&c[0]:00FEFB00
c[1]:2
&c[1]:00FEFB01
c[2]:3
&c[2]:00FEFB02
c[3]:4
&c[3]:00FEFB03

我的电脑本地序为小端序,通过htonl转化为大端序。
通过UDP发送的时候
包内数据转换前为:
[upl-image-preview url=http://discuss.seekloud.org:50080/assets/files/2020-07-03/1593760751-686794-image.png]

转换后为:
[upl-image-preview url=http://discuss.seekloud.org:50080/assets/files/2020-07-03/1593760774-480197-image.png]

在转化后发送的数据和原始数据值是一样的。所以一般在传输和接收时最好转换一下字节序。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值