系统平台大小端问题

守給你的承諾、 提交于 2019-12-07 11:08:48

Internet上的数据以大端方式在网络上传输!!!

常见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 

Socket编程中经常采用第二种方法。整个传输过程如下:发送端将本机的数据转换成网络的字节顺序(调用API函数htonl或htons),然后发送;接收端收到网络数据后,先将数据转换成本机的字节顺序(调用API函数ntohl或ntohs),然后再进行其它操作——如此就能保证“会议精神”在通信双方的正确传达了!这个过程中用到的几个API函数:ntohl、htonl、ntohshtons,名字都差不多,很难区分。但是如果知道了它们的来历,问题也就不存在了:n是network,网络的意思;h是host,本地主机的意思。

    Linux 系统 #include <arpa/inet.h> 

   Windows系统 :#include<Winsock2.h>

   ntohl,就是将32位的u_long类型的数据从网络字节顺序转换成本机字节顺序(htonl的字节顺序转换过程与ntohl相反);

   ntohs,就是将16位的u_short类型的数据从网络字节顺序转换成本机字节顺序(htons的字节顺序转换过程与ntohs相反)。

如何知道简单的知道本机的字节顺序呢?有个很简单的方法,如下: 

BOOL IsLittleEndian(void) 
{ 
  short wValue = 0x5678; 
  return (*((char*)&wValue) == 0x78); 
} 
//返回true为小端,返回false为大端

 

什么时候要进行大小端字节序的转换

 网络协议规定接收到得第一个字节是高字节,存放到低地址,所以发送时会首先去低地址取数据的高字节。

小端-小端 网络传输字节过程:

       发送方网络协议函数发送时会首先去低地址取数据(想要取高字节,真正取得是低字节),接收方网络协议函数接收时会将接收到的第一个字节存放到低地址(想要接收高字节,真正接收的是低字节),所以最后双方都正确的收发了数据。

大端-大端 网络传输字节过程:

       发送方网络协议函数发送时会首先去低地址取数据(取到高字节),接收方网络协议函数接收时会将接收到的第一个字节存放到低地址(接收到高字节),所以最后双方都正确的收发了数据。

     相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。所以,如果网络两端的CPU字节序不一致,最好将小端那边转化成和socket传输一样的大端字节序,而大端那边则不用管。

       特殊情况:Java的存储字节序和网络字节序一致,Internet上的数据以大端方式在网络上传输!!!,所以java数据是大端存储。

short 或者 long的数据在进行通信的时候最好养成:
1、发送的时候使用:htons/htonl
2、接收的时候使用:ntohs/ntohl
不用int型的数据通信,也可以用字符串通信,发送方利用sprintf组织,接收方利用atoi进行转换

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!