网络传输 大小端


小端:低地址存放的是数据的低位
大端:低地址存放的是数据的高位
 
数据0X1234, 12是数据的高位,34是数据的低位
 

#if (('1234' >> 24) == '1')
printf("little\n");
#elif (('4321' >> 24) == '1')
printf("big\n");
#endif

 
 
 
 
如果通信的两端没有进行大小端转换,并且双方的大小端不一致,数据通信才会出错 
在ulu_C3的项目中恰好由于通信的双方都是小端的,所以没出现问题
 
 
常见的CPU架构的字节序吧:
      Big Endian : PowerPC、IBM、Sun
      Little Endian : x86、DEC
      ARM的大小端是可选的。
 

常见的CPU、操作系统上使用的字节顺序 
CPU 操作系统 字节顺序 
x86 (Intel、AMD等) 所有 little-endian 
DEC Alpha 所有 little-endian 
HP-PA NT little-endian 
HP-PA UNIX big-endian 
SUN SPARC 所有 big-endian 
MIPS NT little-endian 
MIPS UNIX big-endian 
PowerPC NT little-endian 
PowerPC 非NT big-endian 
RS/6000 UNIX big-endian 
Motorola m68k 所有 big-endian 
一般来说,我们不用关心字节顺序问题,除非要涉及到跨平台的通信和资源共享

 

(网络传输协议TCP/IP采用的是big- endian)。

假设现在要在使用不同字节顺序的机器之间传输和交换数据,那该怎么办呢?(同样的数据,不同的机器可能有不同的理解,岂不是有悖初衷!)有两种方法,一种是全部转换成文本来传输,另一种是双方都按照某一方的字节顺序来传输(这时就有一个不同字节顺序之间的相互转换问题)。 

 

Socket编程中经常采用第二种方法。整个传输过程如下:

发送端将本机的数据转换成网络的字节顺序(调用API函数htonl或htons),然后发送;

接收端收到网络数据后,先将数据转换成本机的字节顺序(调用API函数ntohl或ntohs),然后再进行其它操作——如此就能保证“会议精神”在通信双方的正确传达了!

 

cetty-core/src/cetty/buffer/ByteOrder.cpp

大小端问题主要涉及的是非单字节非字符串外的其余数据的表示和传递,如short型、int型等

大小端的转换只针对整数类型:short, int, long之类

对于char类型,二进制的字节流类型不存在大小端之间的转换 

http://www.cnblogs.com/my_life/articles/5351631.html

projects/authserver/ChatMsg.cpp

 

http://blog.csdn.net/u013281495/article/details/51166210

因为字节序往往和具体CPU架构有关,所以 如果你知道你的程序主要用户群是什么平台,为了方便或者效率,你可以除了socket端口等需要在主机字节序和网络字节序之间转换外,其余数据的传递直接无视。例如 现在很多端游 都是如此。

因为现在大多数人使用的计算机都是X86体系结构的CPU+Windows操作系统,这部分用户基本就是主流玩家,其他平台的玩家,除非获得的回报率足够多,否则没必要花费太多时间关注。
先来说一下,常见的CPU架构的字节序吧:
      Big Endian : PowerPC、IBM、Sun
      Little Endian : x86、DEC
      ARM的大小端是可选的。
最近随着移动终端(大多为ARM处理器)和移动互联网的爆发式发展,以后的游戏平台就不得不考虑一下大小端问题了。
大小端问题主要涉及的是非单字节非字符串外的其余数据的表示和传递,如short型、int型等。判断主机大小端的方法有很多,常见的是联合体判断法,代码如下:

01.bool isBigEndian()  
02.{  
03.    union
04.    {  
05.        int a;  
06.        char b;  
07.    }num;  
08.    num.a = 0x1234;  
09.    return ( num.b == 0x12 )   
14.}

出于效率考虑,我们有理由也完全应该 把大小端的处理放在客户端,在客户端socket过来时把服务器主机的大小端通知给客户端,这样服务器就不需要改动,直接传递数据就行,这时候可以在客户端代码中封装几个宏,在客户端在收到数据后,根据那些宏来判断是否转换以及得出转换后的数值。大小端转换最有效也是最常见的方法就是移位法:

#define __SWP16(A)   (( ((uint16)(A) & 0xff00) >> 8)    | \  
(( (uint16)(A) & 0x00ff) << 8))  

#define __SWP32(A)   ((( (uint32)(A) & 0xff000000) >> 24) | \  
(( (uint32)(A) & 0x00ff0000) >> 8)   | \  
(( (uint32)(A) & 0x0000ff00) << 8)   | \  
(( (uint32)(A) & 0x000000ff) << 24)) 

聊了那么多,可能很多人要问 为什么 主机的字节序不统一呢? 这是因为 各个CPU厂商出于不同的逻辑考量,换句话说 大端和小端有其各自的优势

我们知道计算机正常的内存增长方式是从低到高(当然栈不是),取数据方式是从基址根据偏移找到他们的位置,从他们的存储方式可以看出,大端存储因为第一个字节就是高位,从而很容易知道它是正数还是负数,对于一些数值判断会很迅速

小端存储 第一个字节是它的低位,符号位在最后一个字节,这样在做数值四则运算时从低位每次取出相应字节运算,最后直到高位,并且最终把符号位刷新,这样的运算方式会更高效,也更符合我们手算的方式。当然这些都是自己的理解,如有不对,还望指正。

 

以下内容为自己总结:(协议部分都是大端,应用可以自己定 )

1、编程时,ip和port需要转换成网络字节序,这是网络协议的规定,注意,ip和port并不是到达应用层数据的一部分,而是网络层和传输层头部的一部分,是属于协议的一部分协议;

2、我们发送的数据是真正从发送端的应用层传输到接收端的应用层的数据,如果发送端和接收端字节序不一样,那么就要考虑字节转换。其根本是:网络传输不一定要统一大端,小端也可以,只要保证2端一致就行了。因为服务器负担大,这些工作就由客户端去做,可以有以下两种方式:1)编程之前,用文档约束好,服务器采用的是大端或者小端,然后客户端根据自己的大小端情况去转换成与服务器一样的字节序再发送和接受;2)客户端连接服务器后,服务器先发送一个表示大小端的1字节的数据到客户端,客户端接收后得知服务器的大小端,以后发送和接收数据时作大小端的调整再发送和接收。

 

=============================================

http://blog.chinaunix.net/uid-15014334-id-4062785.html

建立好socket连接之后,
在小端模式下,发送数据0x12345678
通过wireshark抓包发现得到的数据为78562312,在接收端按字符接收并按字符打印为78563412
在大端模式下,发送数据0x12345678
通过wireshark抓包发现得到的数据为12345678,在接收端按字符接收并按字符打印为12345678

wireshark都是从地地址处开始发送数据的

 

=======================

http://bbs.bccn.net/m.thread.php?tid=396454

大端:低地址是高位数据

小端:低地址是低位数据

无论发送还是接收都是从低位开始的

先发的数据先被收到(有序的)

例子1大小端传输:
    如小端机器发送short的0x0806,即高地址存放0x08,低地址存放0x06----------发送的时候从低地址开始读取,即发送出去是0x0806(先发06,再发08;先收06,再收08)--------大端主机依次读取从低地址开始存放数据,就是低地址存放0x06,高地址存放0x08,但是这个大端字节序,主机会把它解释为0x0608.

例子2大端到大端传输: 
    如大端端机器发送short的0x0806,即高地址存放0x06,低地址存放0x08----------发送的时候从低地址开始读取,即发送出去是0x0608(先发08,再发06;先收08,再收06)--------大端主机依次读取从低地址开始存放数据,就是低地址存放0x08,高地址存放0x06,主机会把它解释为0x0806.结果正确

例子3小端到小端传输: 
    如小端机器发送short的0x0806,即高地址存放0x08,低地址存放0x06----------发送的时候从低地址开始读取,即发送出去是0x0806(先发06,再发08;先收06,再收08)--------小端主机依次读取从低地址开始存放数据,就是低地址存放0x06,高地址存放0x08,主机会把它解释为0x0806.结果正确


 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM