系統平臺大小端問題

Internet上的數據以大端方式在網絡上傳輸!!!java

常見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,本地主機的意思。socket

    Linux 系統 #include <arpa/inet.h> 函數

   Windows系統 :#include<Winsock2.h>spa

   ntohl,就是將32位的u_long類型的數據從網絡字節順序轉換成本機字節順序(htonl的字節順序轉換過程與ntohl相反);操作系統

   ntohs,就是將16位的u_short類型的數據從網絡字節順序轉換成本機字節順序(htons的字節順序轉換過程與ntohs相反)。code

如何知道簡單的知道本機的字節順序呢?有個很簡單的方法,以下: 字符串

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

 

何時要進行大小端字節序的轉換it

 網絡協議規定接收到得第一個字節是高字節,存放到低地址,因此發送時會首先去低地址取數據的高字節。

小端-小端 網絡傳輸字節過程:

       發送方網絡協議函數發送時會首先去低地址取數據(想要取高字節,真正取得是低字節),接收方網絡協議函數接收時會將接收到的第一個字節存放到低地址(想要接收高字節,真正接收的是低字節),因此最後雙方都正確的收發了數據。

大端-大端 網絡傳輸字節過程:

       發送方網絡協議函數發送時會首先去低地址取數據(取到高字節),接收方網絡協議函數接收時會將接收到的第一個字節存放到低地址(接收到高字節),因此最後雙方都正確的收發了數據。

     相同字節序的平臺在進行網絡通訊時能夠不進行字節序轉換,可是跨平臺進行網絡數據通訊時必須進行字節序轉換。因此,若是網絡兩端的CPU字節序不一致,最好將小端那邊轉化成和socket傳輸同樣的大端字節序,而大端那邊則不用管。

       特殊狀況:Java的存儲字節序和網絡字節序一致,Internet上的數據以大端方式在網絡上傳輸!!!,因此java數據是大端存儲。

short 或者 long的數據在進行通訊的時候最好養成:
一、發送的時候使用:htons/htonl
二、接收的時候使用:ntohs/ntohl
不用int型的數據通訊,也能夠用字符串通訊,發送方利用sprintf組織,接收方利用atoi進行轉換

相關文章
相關標籤/搜索