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、ntohs、htons,名字都差不多,很难区分。但是如果知道了它们的来历,问题也就不存在了: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进行转换
来源:oschina
链接:https://my.oschina.net/u/1403215/blog/651825