位元組序:就是數據在記憶體中的存放順序,也可稱之為端模式。 大端模式和小端模式的定義 1) Little-Endian就是低位位元組排放在記憶體的低地址端,高位位元組排放在記憶體的高地址端。 2) Big-Endian就是高位位元組排放在記憶體的低地址端,低位位元組排放在記憶體的高地址端。 3) 網路位元組序:TCP/I ...
位元組序:就是數據在記憶體中的存放順序,也可稱之為端模式。
大端模式和小端模式的定義
1) Little-Endian就是低位位元組排放在記憶體的低地址端,高位位元組排放在記憶體的高地址端。
2) Big-Endian就是高位位元組排放在記憶體的低地址端,低位位元組排放在記憶體的高地址端。
3) 網路位元組序:TCP/IP各層協議將位元組序定義為Big-Endian,因此TCP/IP協議中使用的位元組序通常稱之為網路位元組序
什麼是高位位元組,低位位元組?
一般一個16位(雙位元組)的數據,比如 FF1A (16進位),(4位二進位用一個十六進位表示)
那麼高位位元組就是FF,低位是1A
如果是32位的數據,比如 3F68415B
高位字(不是位元組)是3F68
低位字是415B
右邊是低位,左邊是高位
include <stdio.h> #include <arpa/inet.h> int main(int argc, char *argv[]) { unsigned int x = 0x12345678; unsigned char* p = (unsigned char*)&x; //小端位元組序 printf( "%p->%0x\n%p->%0x\n%p->%0x\n%p->%0x\n", p+0, *(p+0), p+1, *(p+1), p+2, *(p+2), p+3, *(p+3) ); printf( "---------------------\n" ); //h:主機位元組序 n:網路位元組序 l:long unsigned int y = htonl( x ); p = ( unsigned char* )&y; printf( "%p->%0x\n%p->%0x\n%p->%0x\n%p->%0x\n", p+0, *(p+0), p+1, *(p+1), p+2, *(p+2), p+3, *(p+3) ); return 0; }
輸出結果:
0x7fff3bb55708->78
0x7fff3bb55709->56
0x7fff3bb5570a->34
0x7fff3bb5570b->12
---------------------
0x7fff3bb5570c->12
0x7fff3bb5570d->34
0x7fff3bb5570e->56
0x7fff3bb5570f->78
第一種結果:
0x7fff3bb55708->78
0x7fff3bb55709->56
0x7fff3bb5570a->34
0x7fff3bb5570b->12
地址從08--->0b屬於增長, 08這個低地址放的是78, 78這個數是低位位元組, 這種情況屬於低地址放低位位元組,高地址放高位位元組, 所以叫:小端位元組序
第二種結果:
0x7fff3bb5570c->12
0x7fff3bb5570d->34
0x7fff3bb5570e->56
0x7fff3bb5570f->78
把主機位元組序轉換成了網路位元組序, 這種情況屬於低地址放高位位元組,高地址放低位位元組,所以叫:大端位元組序
---------------------------------------------------------------------------------------------------------------------------------------------------------
位元組序轉換相關API:
htonl:主機位元組序轉換成網路位元組序
inet_addr:函數原型:in_addr_t inet_addr(const char *cp)
作用:把ip地址格式轉成網路位元組序
unsigned int addr = inet_addr( "192.168.1.100" ); printf( "%u\n", addr ); printf( "0x%0x\n", addr );
結果:
1677830336
0x6401a8c0
這兩個數是一樣的
ntohl: 網路位元組序轉主機位元組序
unsigned int haddr = ntohl( addr ); printf( "%u\n", haddr ); printf( "0x%0x\n", haddr );
inet_ntoa:網路位元組序,轉ip地址格式
struct in_addr ipaddr; ipaddr.s_addr = addr; printf( "%s\n", inet_ntoa( ipaddr ) );