端序和位域的关系

端序包括字节序和位序。


结论a:

struct定义字段按照从内存低位地址到高位地址排列。


简单回顾大小尾:

大尾序符合人们习惯,数的高位分布在内存中的低位地址。

小尾序相反。


字节序主要用在网络通讯。

使用场景:当本地的多字节整数如short或long,需要发送到网络。

不同的设备可能使用不同的字节序(包括大尾序、小尾序等,具体取决于CPU类型),导致多字节整形变量在内存中排列的顺序不同, 直接发送到网络,导致字节序不同的设备发送同样的内容产生不同的效果。所以网络发送前,整形变量需要进行一次转换,转换为网络序(网络序为大尾序)。


比如,实际值0x12345678,在大尾序中,内存从低位地址到高排地址列顺序为0x12345678,小尾序中从低到高为0x78563412。它们都是以字节为基本单元的。


除了字节序,还有位序。如果只是从事上层开发,应该不用关注到位序。

不过如果刚看过linux中tcp.h、ip.h的定义并需要使用的同学,可能还有疑问。

位序和字节序一样,大尾在内存中的排列符合人类习惯,在内存中高位数值分布在低位地址(或许不应该这么叫),小尾正好相反。


结论b:

对于发送同一个字节,大尾和小尾在内存中分布是不同的,但是能达到同样的效果,底层在发送时,发送的内容取决于字节的实际值,和字节内的内存中顺序无关。


下面给出linux的ip.h文件中的一部分:

struct iphdr {
#ifdef __LITTLE_ENDIAN_BITFIELD
 __u8 ihl:4,
 version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
 __u8 version:4,
 ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
 __u8 tos;
 __be16 tot_len;
 __be16 id;
 __be16 frag_off;
 __u8 ttl;
 __u8 protocol;
 __u16 check;
 __be32 saddr;
 __be32 daddr;

};

先给出结论:

结论c:

开发者可以不用关心位序相关的内容,直接使用相关字段即可。

下面简单验证上面的结论。

已知struct中的字段排列为由低位到高位,令 version=1,ihl=2,

在大尾设备上,根据上面结构体,内存中的内容为:0001 0002,实际值为0001 0002

在小尾设备上,如果version字段在前,由结论a,得到内存中的内容为:1000 2000,实际值为0002 1000

在小尾设备上,根据上面结构体,内存中的内容为:2000 1000,实际值为0001 0002

可以看出,第三组与第一组的实际值吻合,由结论b,两个字节内容相同即可产生相同的报文,得知验证成功。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值