端序和位域的关系

来源:互联网 发布:网络病毒有哪些 编辑:程序博客网 时间:2024/05/15 08:48

端序包括字节序和位序。


结论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
原创粉丝点击