关于字节序的学习

在不同的计算机体系结构中,其字节的存储机制会有所不同,所以就会引发通信双发应以什么样的顺序进行传送。
如果双方没有一致的规则,那通信就可能失败。

目前在各种体系的计算机中,通常要么采用big-endian要么就会采用little-endian这两种字节存储机制中的一种。
所谓的big-endian也就是数据的高字节位会放在存储器的底地址中;
所谓的little-endian也就是数据的高字节位会放在存储器的高地址中。

根据上述定义,我们可以测试计算机的endian模式。
方法1:
typedef union _u_data
{
    int int_value;
    char char_value;
}u_data;

u_data value;
value.int_value = 0x11223344;
if (0x44 == value.char_value)
{
    printf("\nlow byte low address, little endian\n");
}
else if (0x11 == value.char_value)
{
    printf("\nhigh byte low address, big endian\n");
}
else
{
    printf("\nerror?\n");
}

方法2:
int value = 0x11223344;
char* pchar = (char*)&value;

if ((0x44 == *pchar) && (0x33 == *(pchar+1)))
{
    printf("\nlow byte low address, little endian\n");
}
else if ((0x11 == *pchar) && (0x22 == *(pchar+1)))
{
    printf("\nhigh byte low address, big endian\n");
}
else
{
    printf("\nerror?\n");
}
通过实验验证,与我们预期的相吻合。

前面有说过,不同体系的计算机其endian模式可能是不同的,所以在行通信时,就要考量到endian这一因素。
我们要写出endian-free的代码,这样其可移植性,以及可重用性都会更好,代码的价值才可能会更大。

我们知道网络字节序总是big endian模式,而主机字节序可能是big endian也可能是little endian。
所以在数据通信中,发送端需要将数据转换成big-endian再传输;
接收端需要将接收到来自网络中的big-endian的数据转换成适合自己endian模式的数据,
这样双方通信才不会出错。

还好linux系统提供了以下几个API帮助我们完成这个需求:
unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);

htonl means host to network, type long;
htons means host to network, type short;
ntohl means network to host, type long;
ntohs means network to host, type short;

如果没有这几个用于数据转换的API,会怎么办?
假设网络字节序依然是big endian,
如果sender和receiver都是big endian,那数据本身不需要转换,所以不会有问题;
如果sender和receiver都是little endian,这时会将错就错,也不会有问题,
比如0x11223344在网络上会变成0x44332211,传送到receiver端时会变回成0x11223344;
如果sender是big endian,而receiver是little endian,那也就是big endian数据会变成
little endian的数据,比如0x11223344,在网络上依然是0x11223344,到了receiver会
变成0x44332211,错了;
如果sender是little endian,而receiver是big endian,那数据也会出错,
比如0x11223344,在网络上会先变成0x44332211,到了receiver依然是0x44332211。

1. 上面最近的一段文字还未加验证;
2. 有机会时学习一下linux提供的这几个API。

希望自己变得越来越好!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值