● 位元組序的定義
位元組序,顧名思義位元組的順序,再多說兩句就是大於一個位元組的資料在記憶體中的存放順序(一個位元組的資料當然就無需談順序的問題)。
在大部分的開發中我們不需要考慮位元組序的問題。唯有在跨平台以及網路程式應用中位元組序才是一個應該被考慮的問題。
● 網路應用的位元組序
網路位元組序是TCP/IP規定好的一種資料表示格式,它與具體的CPU類型、作業系統無關,從而可以保證資料在不同主機之間傳輸時能被正確解釋。網路位元組順序採用big endian排序方式。
在網路編程時,並不是什麼時候都要考慮位元組序問題。那麼什麼時候需要考慮呢?
Intel CPU使用的都是little endian。
實際上如果是應用程式層的資料,即對TCP/IP來說是透明的資料,不用考慮位元組序的問題。因為接收端收到的順序是和發送端一致的。
但對於TCP/IP關心的資料(IP地址、連接埠)來說就不一樣了。
例如我指定了一個連接埠號碼:
unsigned short port = 0x0012 (十進位18)
把這個連接埠號碼傳個TCP/IP建立一個socket串連。
sockaddr_in addr;
addr.sin_family = AF_INET; //使用互連網際協議,即IP協議
addr.sin_port = port;
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
因為網路位元組序是big endian,即低地址存放的是數值的高位,所以TCP/IP實際上把這個port解釋為0x1200(十進位4608)。本來打算是要在連接埠18建立串連的,但TCP/IP協議棧卻在連接埠4608建立了串連。
當一個資料是應用程式層和TCP/IP都需要關心的時候,需要考慮這個資料的位元組序(一般而言就是IP地址和連接埠號碼)。
我覺得網路位元組序的問題其實可以隱藏在TCP/IP中的,不知道為什麼沒有那麼做?
● 位元組序轉換函式
htons 把 unsigned short 類型從主機序轉換到網路序
htonl 把 unsigned long 類型從主機序轉換到網路序
ntohs 把 unsigned short 類型從網路序轉換到主機序
ntohl 把 unsigned long 類型從網路序轉換到主機序
這幾個函數很好記,比如htons中hton代表host to network, s代表unsigned short
char FAR * inet_ntoa( struct in_addr in);
將一個IP轉換成一個互連網標準點分格式的字串。
in_addr_t inet_addr(const char *cp);
將一個點分十進位的IP轉換成一個長整數型數(u_long類型)。傳回值已是網路位元組順序,可以直接作為internet 地址