做网站哪家公司好,青岛运营网络推广业务,动漫设计与制作专业的应用领域,网站建设中服务器的搭建方式有几种一、什么是字节序
在谈字节序前讲个小故事#xff0c;在小说《格列佛游记》中#xff0c;有两派势力为了吃鸡蛋的时候儿到底是先打破大的一端还是打破小的一端展开了战争#xff0c;而且这场战争持续了很久。后来#xff0c;1980年#xff0c;Danny Cohen在论文On …一、什么是字节序
在谈字节序前讲个小故事在小说《格列佛游记》中有两派势力为了吃鸡蛋的时候儿到底是先打破大的一端还是打破小的一端展开了战争而且这场战争持续了很久。后来1980年Danny Cohen在论文On Holy Wars and a Plea for Peace中引用了这个故事来处理一场关于数据传输时字节该以什么样的顺序进行传送的争论所以在计算机的世界中也才有了字节序这个概念。 字节序又称端序、尾序英文单词为Endian由于上面的鸡蛋的打破的大小端两种情况所以这里也分成了little Endian(小头或小端模式),big Endian大头或大端模式。 这时候儿大家会不会突然明白这不和汽车的左舵和右舵一样么没有什么对错只是设定的不同。 在开发者或者说常见的体系中一般是以小头字节序多比如常见的x86体系的电脑基本都是小端模式。那么小端模式和大端模式是什么样子呢大家都知道电脑的内存是从低地址向高地址增长的对于存储一个数如果在低地址存储低字节高地址存储高字节那就是大端模式反之为小端模式。举个例子就明白了 一个十六进制的数0x12345678举十六进制是为了容易表述和十进制一样,字节0x12是高字节依次向低字节过渡最低是0x78。如果内存是下面的情况 地址0 1 2 3 (地址由低到高)数据78 56 34 12则为小端模式如果如下面的情况则为大端模式地址0 1 2 3 (地址由低到高)数据12 34 56 78大家有没有发现大端模式符合人们的日常感官看法因为人们一般书写数字都是从左到右从高位和低位的。如果大家想更直观的看可以在VS或者其它的IDE中写个十六进制的变量然后在内存观察器中查看就可以看到上面的类似的场景了非常直观。 常见的大小端的机器如下 小端模式x86MOS Technology 6502Z80VAXPDP-11等处理器 大端模式Motorola 6800Motorola 68000PowerPC 970System/370SPARC除V9外等处理器 可配置模式ARM, PowerPC (除PowerPC 970外), DEC Alpha, SPARC V9, MIPS, PA-RISC and IA64等处理器 说是常见其实对大多数开发人员可能基本都不会遇到几个。
二、应用场景
这时如果大家跳脱出来决定所有的数据都单纯以字节表示不就没这个大小端之争了么确实但计算机一开始的发展是没有标准的。就和全世界有米、尺、英尺等等一样。所以为了表示各种类型的数据搞计算机的人怎么痛快怎么来嘛。你想看着舒服我就想用着痛快你想高位存储在高地址低位存储在低字节我就反着来。特别是需要用多个字节才能表示的整形int,short,long等等以及一些其它情况大家肯定是各有所好而且有的时候就是故意的对着干。 但对程序员来说最常遇到的当然是小端X86架构平台。即使开发移动程序也是在PC上开发不是。 另外一个场景对开发者来说非常常见网络编程网络数据的传输是以大端模式进行的。所以大家还记不记得在传递端口号时要做一个转换使用类似下面的函数
//主机字节序到网络字节序
htons:unsigned short类型转换到网络序
htonl:unsigned long类型转换到网络序
//网络字节序到主机字节序
ntohs:unsigned short类型转换到主机序
ntohl:unsigned long类型转换主机序其它的大小端模式基本都是比较专业的开发才可能遇到了。
三、实际应用
在实际应用中如果数据是以字节表示的则不会有任何问题即使在多个大小端的协议或者平台进行处理都不会有问题比如图像的字节点阵。另外一个现象是如果大小端传输的对称性也没有问题。举个例子当以小端字节传递数据经过大端协议但对方接收也是小端处理正常情况下也不会有问题这就是在进行了网络开发时为什么只是把端口号啥的需要大端解析的数据转换一下其它的传输的字节流数据不是单纯的字节流是小端表示数据转换过来的如int,long等在接收后进行转换时不会出问题的原因。不过如果非对称的则需要进行处理比如发送是大端接收是小端无论中间过多少手大小端最终的部分都需要转换中间部分只负责传输。 为了保持安全一般C/C都有查看大小端的方法 1、使用宏定义 BYTE_ORDER__宏值为__ORDER_LITTLE_ENDIAN即当前环境为小端模式而值为__ORDER_BIG_ENDIAN__则为大端模式 2、通过编程实现 可以使用联合体或位运算的方式来处理
//联合体
union endian {int d;char order[4];
}Endian;
bool BigEndian() {Endian.d 1;return (Endian.order[0] 0);
}
//位
bool BigEndian() {int td 1;return (*(char*)td 0);
}3、C中的库 使用std::endian不过它在C20才支持。使用的方法就不举例了非常简单大家可以查看一下帮助。
四、总结
其实字节序这种东西如果不是经常和多个不同的架构平台打交道的话其实意义真得不是多大。虽然经常应用的网络数据处理是大头的但实际上网传输的基本都有库或者序列化对开发者影响基本消除了。只有个别的如端口啥的可能需要自己处理还都有专门的处理函数。所以对绝大多数开发者来说都可以不需要专门注意这件事当实际遇到相关的场景后再进行处理即可。