網路位元組序
一.位元組序
位元組序是由於不同的主處理器和作業系統,對大於一個位元組的變數在記憶體中的存放順序不同而產生的。
位元組序通常有大端位元組序列和小端位元組序兩種分類方法。
由於主機的千差萬別,主機的位元組序不能做到統一,但是網路上傳輸的數值,它們有統一的規定。網路位元組序:是指多位元組變數在網路傳輸時的表示方法,網路位元組序採用高端位元組序的表示方法。
二.大端位元組序和小端位元組序
位元組序是由於CPU和OS對多位元組變數的記憶體儲存順序不同而產生的。
1.brief introduce:
一個16位的整數,它由兩個位元組構成,在有的系統上會將高位元組放在記憶體的低地址上,而有的系統上則將高位元組放在記憶體的高地址上,所以存在位元組序的問題。
2.位元組序的表示方法有兩種:
1>小端位元組序(Little Endian):在表示變數的記憶體起始地址存放底位元組,高位元組順序存放
2>大端位元組序(Big Endian):在表示變數的記憶體起始地址存放高位元組,底位元組順序存放。
3執行個體:
一個變數的值為0xabcd,在大端位元組序和小端位元組序的系統中兩者的存放順序是不同的.
1>在小端位元組系統中的存放順序:
0xab在地址15~8的地址上,而0xcd在地址7~0的位置上。
2>在大端位元組序系統中的存放順序:
4.程式執行個體:
可以編寫程式來檢測下變數在記憶體中的表示形式,以確定系統中的位元組序為大端位元組序還是小端位元組序。
(1)位元組序結構:
程式先建立一個公用體類型address,用於測試位元組序,成員value是int 類型變數,可以通過成員byte來訪問value變數的高位元組和低位元組。
typedef union{
unsigned int value;
unsigned char byte[2];
}addr;
(2)變數聲明,聲明一個to類型的變數typeordr,給變數value賦值為0xabcd,由於在類型addr中,value和byte成員共用同一塊記憶體,所以可以通過byte的不同成員來訪問value的高位元組和低位元組。
(3)程式:
int main(int argc,char *argv)
{
addr typeorder;//一個to類型的變數
typeorder.value= 0xabcd;
/*小端位元組序檢查*/
if(typeorder.byte[0] == 0xcd &&typeorder.byte[1]==0xab){
printf(“Low endian bye order\n”);
printf(“byte[0]:0x%x,byte[1]:0x%x\n”,typeorder.byte[0],typeorder.byte[1]);
}
/*大端位元組序判斷*/
if(typeorder.byte[0] == 0xab &&typeorder.byte[1]==0xcd){
printf(“High endian byte order\n”);
printf(“byte[0]:0x%x,byte[1]:0x%x\n”,typeorder.byte[0],typeorder.byte[1]);
}
return 0;
}
5.進行網路位元組序轉換的函數有htons,htonl,ntohs(),ntohl()等,其中s表示short資料類型,l是long資料類型的意思,h是host既主機的意思,n是network即網路的意思。
1>htons(host to net short):表示對short類型的變數,從主機位元組序轉換為網路位元組序。
2>ntohs(net to host short):表示對short類型的變數,從網路位元組序轉換為主機位元組序。
3>htonl(host to net long):表示對long類型的變數,從主機位元組序轉換為網路位元組序
4>ntohl(net to host long):表示對long類型的變數,從網路位元組序轉換為主機位元組序。
6.由於在網路中網路位元組序採用高端位元組序的表示方法。因此位元組序轉換函式在不同平台上的實現是不同的,在小端主機位元組序的平台要進行轉換,而在大端主機位元組序的平台上是不需要進行轉換的。
例如:通過下面的實現方式可以相容不同的平台:
#if ISLE
/*小端位元組序平台叫用此部分代碼*/
long htonl(longvalue)
{
Return ((value << 24) | ((value <<8)&0x00ff0000) |((value>>8)&0x0000ff00)|(value>>24));
}
#else if ISBE
/*大端位元組序平台叫用此部分代碼*/
long htonl(longvalue)
{
/*由於位元組序一致,不需要進行轉換*/
return value;
}
#endif