一般咱們認爲網絡字節序爲標準順序,封包的時候,將主機字節序轉換爲網絡字節序,拆包的時候要將網絡字節序轉換爲主機字節序。數組
原覺得還要本身寫函數,其實網絡庫已經提供了。
主機到網絡:short/int/long IPAddress.HostToNetworkOrder(short/int/long)
網絡到主機:short/int/long IPAddress.NetworkToHostOrder(short/int/long)
主機字節序指低字節數據存放在內存低地址處,高字節數據存放在內存高地址處,如:
int x=1; //此時x爲主機字節序:[1][0][0][0] 低位到高位
int y=65536 //此時y爲主機字節序:[0][0][1][0] 低位到高位
咱們經過主機到網絡字節序的轉換函數分別對x和y進行轉換獲得他們對應的網絡字節序值,網絡
網絡節序是高字節數據存放在低地址處,低字節數據存放在高地址處,如:
int m=IPAddress.HostToNetworkOrder(x);
//此時m爲主機字節序:[0][0][0][1] 高位到低位
int n=IPAddress.HostToNetworkOrder(y);
//此時n爲主機字節序:[0][1][0][0] 高位到低位
通過轉換之後,咱們就能夠經過
byte[]btValue=BitConverter.GetBytes(m);
獲得一個長度爲4的byte數組,而後將這個數組設置到報文的相應位置發送出去便可。
一樣,收到報文後,能夠將報文按域拆分,獲得btValue,使用
int m=BitConverter.ToInt32(btValue,0);//從btValue的第0位開始轉換
獲得該域的值,此時還不能直接使用,應該再用網絡到主機字節序的轉換函數進行轉換:
int x=IPAddress.NetworkToHostOrder(m);
這時獲得的x纔是報文中的實際值。socket
ps:網絡字節序與主機字節序
不一樣的CPU有不一樣的字節序類型 這些字節序是指整數在內存中保存的順序 這個叫作主機序
最多見的有兩種
1. Little endian:將低序字節存儲在起始地址
2. Big endian:將高序字節存儲在起始地址
LE little-endian
最符合人的思惟的字節序
地址低位存儲值的低位
地址高位存儲值的高位
怎麼講是最符合人的思惟的字節序,是由於從人的第一觀感來講
低位值小,就應該放在內存地址小的地方,也即內存地址低位
反之,高位值就應該放在內存地址大的地方,也即內存地址高位
BE big-endian
最直觀的字節序
地址低位存儲值的高位
地址高位存儲值的低位
爲何說直觀,不要考慮對應關係
只須要把內存地址從左到右按照由低到高的順序寫出
把值按照一般的高位到低位的順序寫出
二者對照,一個字節一個字節的填充進去
例子:在內存中雙字0x01020304(DWORD)的存儲方式
內存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04
例子:若是咱們將0x1234abcd寫入到以0x0000開始的內存中,則結果爲
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
x86系列CPU都是little-endian的字節序.
網絡字節順序是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操做系統等無關,從而能夠保證數據在不一樣主機之間傳輸時可以被正確解釋。網絡字節順序採用big endian排序方式。JAVA 中默認是Big Endian,C++和其餘語言通常是Little Endian。
爲了進行轉換 bsd socket提供了轉換的函數 有下面四個
htons 把unsigned short類型從主機序轉換到網絡序
htonl 把unsigned long類型從主機序轉換到網絡序
ntohs 把unsigned short類型從網絡序轉換到主機序
ntohl 把unsigned long類型從網絡序轉換到主機序
在使用little endian的系統中 這些函數會把字節序進行轉換
在使用big endian類型的系統中 這些函數會定義成空宏
一樣 在網絡程序開發時 或是跨平臺開發時 也應該注意保證只用一種字節序 否則兩方的解釋不同就會產生bug.
注:
一、網絡與主機字節轉換函數:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
二、不一樣的CPU上運行不一樣的操做系統,字節序也是不一樣的,參見下表。
處理器 操做系統 字節排序
Alpha 所有 Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 所有 Little endian <-----x86系統是小端字節序系統
Motorola680x() 所有 Big endian
MIPS NT Little endian
MIPS UNIX Big endian
PowerPC NT Little endian
PowerPC 非NT Big endian <-----PPC系統是大端字節序系統
RS/6000 UNIX Big endian
SPARC UNIX Big endian
IXP1200 ARM核心 所有 Little endian函數