一個IP地址是由小數點分開的十進制數表示的,我們稱之為點分十進制表示法。其中每一個十進制數代表一個字節的無符號數值(按照網絡字節序)因為每個字節都是無符號的8位數值,這就限制了每一個字節所能表示的范圍是0~255.
Internet地址分類
一個Internet地址是由網絡地址和主機地址構成的。
我們知道IP地址由32位二進制構成,但是網絡地址和主機地址之間的界限並不是固定的,而界限的確定取決於地址的分類,下表總結了IP地址分類的方法:
理解網絡掩碼:
網絡掩碼的作用在於把網絡地址從IP地址從提取出來,實際上代表網絡掩碼的IP號和某一特定的IP地址進行“按位與”操作。
如果我們需要建立自己的IP網絡,那么就必須確定網絡掩碼,如下圖:
軟件有時候需要提供將IP地址進行分類的能力,下面的例子就展示了這個操作:
---------UNDONE(此處代碼待添加)
分配IP地址
ip地址是通過InterNIC分配給不同的組織和個人的。但是並非所有的IP地址都是可以用來分配的,其中也有一些私有的,或者說是預留出來的。
私有IP
一般IP地址都需要在InterNIC進行登記,但是如果你的系統沒有直接連接到Internet,那么久不需要全球唯一的地址,這個時候就可以使用私有IP地址來替代。
RFC1597就是描述怎么分配私有IP地址的文檔。
最后到底選擇哪一種IP地址在很大的程度上取決於所需要建立的網絡數量,分離的網段以及每個網段上主機的數目。
保留IP地址
保留IP地址的數量很多,在RFC1166文檔中有記錄。下面就是一個保留IP地址的實例:
操作IP地址
inet_addr()函數的語法如下:
#include <sys/socket.h> #include <neiinet/in.h> #include <arpa/inet.h> unsigned long inet_addr(const char * string);
這個函數使用string作為輸入參數,並將這個點分十進制的IP地址轉換為32位的二進制表示法,函數的返回值就是這個32位的二進制的網絡字節序。當然如果string不是一個有效的點分十進制IP地址,函數返回INADDR_NONE。另外需要注意的是,當inet_addr函數返回INADDR_NONE的時候,它並沒有建立一個有效的errno值,所以當函數返回錯誤的時候,不要去測試errno的值。
下面的這個例子展示了如何使用函數inet_addr。
。。。。。。。。。UNDONE(此處代碼待添加)
注意:
在新程序中避免使用inet_addr函數,而應該使用inet_aton函數作為代替。因為對於inet_addr函數來說,即使輸入的參數是有效的IP地址:255.255.255.255,他的返回值仍然是INADDR_NONE。
下面我們來說說inet_aton函數:
inet_aton函數是將字符串形式的IP地址轉換為網絡字節序的32位IP地址的改進形式。語法如下:
#include <sys/socket.h> #include <neiinet/in.h> #include <arpa/inet.h> int inet_aton(const char* string, struct in_addr*addr);
參數string表示點分十進制IP地址的ASCII表示。輸出參數addr是一個被新的IP地址跟新的結構。函數調用成功返回非0值。失敗返回0.當然他也沒有建立一個有效的errno值。下面的代碼展示了inet_aton函數的用法:
。。。。。。。。。UNDONE(此處代碼待添加)
下面我們來看看inet_ntoa函數
有時候當用戶連接到你的服務器的時候,需要知道他的IP地址,系統提供了inet_ntoa函數將32位的二進制IP地址表示轉換為點分十進制的字符串形式:
#include <sys/socket.h> #include <neiinet/in.h> #include <arpa/inet.h> char* inet_ntoa(struct in_addr addr);
下面的代碼展示了如何使用inet_ntoa函數:
。。。。。。。。。UNDONE(此處代碼待添加)
需要注意的是inet_ntoa函數的返回值直到下次調用前一直有效。所以如果在線程中使用inet_ntoa的時候,一定要確保每次只有一個線程調用本函數。否則一個線程的返回的結構可能被其他線程返回的結果所覆蓋。
接下來我們來看看inet_network函數。
當我們需要用網絡掩碼將IP地址中的網絡位或者主機位提取出來的時候,如果能將點分十進制的IP地址轉換為主機字節序的32位二進制IP地址形式就方便了,而inet_network函數的作用就是如此、語法如下:
#include <sys/socket.h> #include <neiinet/in.h> #include <arpa/inet.h> unsigned long inet_network(const char* addr);
函數的輸入參數是存儲在字符串addr中的點分十進制IP地址,返回值是主機字節序的32位二進制地址,但是如果輸入參數不正確,返回值是0xFFFFFFFF.
以主機字節序的形式返回結果可以保證用戶安全的使用網絡掩碼,因為如果返回值是網絡字節序的話,那么不同的cPu平台所使用的網絡掩碼和程序代碼就會有差異。下面的例子展示了如何使用inet_network函數。
。。。。。。。。。UNDONE(此處代碼待添加)
我們來看看inet_lnaof函數。
函數inet_lnaof函數是將套接口地址中的IP地址(網絡字節序)轉換為沒有網絡位的主機ID(主機字節序),這個函數為我們省去了很多的麻煩,因為我們不需要對IP地址進行分類,再將主機為從IP地址中提取出來。函數語法如下:
#include <sys/socket.h> #include <neiinet/in.h> #include <arpa/inet.h> unsigned long inet_lnaof(struct in_addr addr);
下面的表提供了一些可以作為inet_lnaof函數輸入的典型例子和返回值:
我們再來看看inet_netof函數
inet_lnaof函數返回的是主機ID,而inet_netof函數返回的是網絡ID,函數語法如下:
#include <sys/socket.h> #include <neiinet/in.h> #include <arpa/inet.h> unsigned long inet_netof(struct in_addr addr);
下表展示了一些例子:
然后我們再來看看inet_makeaddr函數吧。根據之前的內容我們知道使用inet_netof函數和inet_lnaof函數,我們就可以把IP地址中的主機為和網絡位分別提取出來,有時候我們還需要根據提取出來的主機位和網絡為合並為一個新的IP地址。這個時候我們就可以使用inet_makeaddr函數。
#include <sys/socket.h> #include <neiinet/in.h> #include <arpa/inet.h> struct in_addr inet_makeaddr(int net , int host);
下面的例子展示了上面講到的三個函數:
。。。。。。。。。UNDONE(此處代碼待添加)






