0x01、網絡字節順序NBO(Network Byte Order)
按從高到低的順序存儲,在網絡上使用同一的網絡字節順序,可避免兼容性問題;
0x02、主機字節順序HBO(Host Byte Order)
不同的機器HBO不相同,與CPU的設計有關,數據的順序是由CPU決定的,而與操作系統無關;
如Intel x86結構下,short型數0x1234表示為34 12,int型數0x12345678表示為78 56 34 12;
如IBM power PC結構下,short型數0x1234表示為 12 34,int型數0x12345678表示為 12 34 56 78.
由于這個原因,不同體系結構的機器之間不能直接通信,所以要轉換成一種約定的順序,也就是網絡字節順序,其實就是如同power pc那樣的順序。在PC開發中有ntohl和htonl函數可以用來進行網絡字節和主機字節的轉換
0x03、linx系統下,htonl() htons() ntohl() ntohs()的頭文件及函數定義如下:
#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);uint16_t htons(uint16_t hostshort);uint32_t ntohl(uint32_t netlong);uint16_t ntohs(uint16_t netshort);0x04、在windows下,htonl() htons() ntohl() ntohs()的使用說明:
ntohs()簡述:
將一個無符號短整形數從網絡字節順序轉換為主機字節順序。
#include <winsock.h>u_short PASCAL FAR ntohs( u_short netshort);netshort:一個以網絡字節順序表達的16位數。 注釋:本函數將一個16位數由網絡字節順序轉換為主機字節順序。 返回值:ntohs()返回一個以主機字節順序表達的數。 * htons() 簡述:將主機的無符號短整形數轉換成網絡字節順序。
#include <winsock.h>u_short PASCAL FAR htons( u_short hostshort);hostshort:主機字節順序表達的16位數。
注釋:本函數將一個16位數從主機字節順序轉換成網絡字節順序。 返回值:htons()返回一個網絡字節順序的值。
比較:
這2個函數提供了主機字節順序與網絡字節順序的轉換比如網絡字節 為 00 01 u_short a;如何直接對應的話 a=0100; 為什么呢?因為主機是從高字節到低字節的,所以應該轉化后a=ntohs(0001); 這樣 a=0001;
htonl簡述:htonl()表示將32位的主機字節順序轉化為32位的網絡字節順序 htons()表示將16位的主機字節順序轉化為16位的網絡字節順序(ip地址是32位的端口號是16位的 )
將IP地址轉換成長整型:首先,假設你已經有了一個sockaddr_in結構體ina,你有一個IP地址”132.241.5.10” 要儲存在其中,你就要用到函數inet_addr(),將IP地址從點數格式轉換成無符號長整型。使用方法如下:ina.sin_addr.s_addr = inet_addr(“132.241.5.10”); 注意,inet_addr()返回的地址已經是網絡字節格式,所以你無需再調用函數htonl()。 我們現在發現上面的代碼片斷不是十分完整的,因為它沒有錯誤檢查。顯而易見,當inet_addr()發生錯誤時返回-1。記住這些二進制數字?(無符號數)-1僅僅和IP地址255.255.255.255相符合!但這可是廣播地址!所以,記住要先進行錯誤檢查。
怎樣將一個in_addr結構體輸出成點數格式?你要用到函數 inet_ntoa()(“ntoa”的含義是”network to ascii”),就像這樣:PRintf(“%s”,inet_ntoa(ina.sin_addr));它將輸出IP地址。需要注意的是inet_ntoa()將結構體in_addr作為一個參數,不是長整形。同樣需要注意的是它返回的是一個指向一個字符的指針。它是一個由inet_ntoa()控制的靜態的固定的指針,所以每次調用 inet_ntoa(),它就將覆蓋上次調用時所得的IP地址。例如:
char *a1, *a2;..a1 = inet_ntoa(ina1.sin_addr);a2 = inet_ntoa(ina2.sin_addr);printf("address 1: %s ",a1);printf("address 2: %s ",a2);輸出如下:
address 1: 132.241.5.10address 2: 132.241.5.10假如你需要保存這個IP地址,使用strcopy()函數來指向你自己的字符指針。
inet_ntoa()簡述: 將網絡地址轉換成“.”點隔的字符串格式。
#include <winsock.h> char FAR* PASCAL FAR inet_ntoa( struct in_addr in);in:一個表示Internet主機地址的結構。 注釋: 本函數將一個用in參數所表示的Internet地址結構轉換成以“.” 間隔的諸如“a.b.c.d”的字符串形式。請注意inet_ntoa()返回的字符串存放在WINDOWS套接口實現所分配的內存中。應用程序不應假設該內存是如何分配的。在同一個線程的下一個WINDOWS套接口調用前,數據將保證是有效。
返回值: 若無錯誤發生,inet_ntoa()返回一個字符指針。否則的話,返回NVLL。其中的數據應在下一個WINDOWS套接口調用前復制出來。 參見: inet_addr().
測試代碼如下
#pragma comment (lib,"Ws2_32.lib")//noths.obj : error LNK2001: unresolved external ymbol _inet_addr@4#include <winsock.h>#include <iostream.h>#include <stdio.h>int main(int aargc, char* argv[]){ struct in_addr addr1,addr2; unsigned long l1,l2; l1= inet_addr("192.168.0.74"); l2 = inet_addr("211.100.21.179"); memcpy(&addr1, &l1, 4); memcpy(&addr2, &l2, 4); printf("%s : %s /n", inet_ntoa(addr1), inet_ntoa(addr2)); //注意這一句的運行結果 printf("%s /n", inet_ntoa(addr1)); printf("%s /n", inet_ntoa(addr2)); return 0;}實際運行結果如下:
192.168.0.74 : 192.168.0.74 //從這里可以看出,printf里的inet_ntoa只運行了一次。192.168.0.74211.100.21.179inet_ntoa返回一個char ,而這個char 的空間是在inet_ntoa里面靜態分配的,所以inet_ntoa后面的調用會覆蓋上一次的調用。第一句printf的結果只能說明在printf里面的可變參數的求值是從右到左的,僅此而已。
新聞熱點
疑難解答