Linux 地址轉換函數

      IP 地址是由小數點分開的十進制數表示的,我們稱之爲點分十進制表示法。

Internet 地址分類

     一個 Internet 地址是由 網絡地址 和 主機地址 構成的。

     IP 地址佔 32 位,但是 網絡地址 和 主機地址 之間的界限並不是固定的,而界限的確定取決於地址的分類,下表總結了 IP 地址分類的方法:

image

理解網絡掩碼:

     網絡掩碼的作用在於把網絡地址從 IP 地址從提取出來,實際上代表網絡掩碼的 IP 號和某一特定的 IP 地址進行“按位與”操作。

     如果我們需要建立自己的 IP 網絡,那麼就必須確定網絡掩碼,如下圖:

image

      軟件有時候需要提供將 IP 地址進行分類的能力,下面的例子就展示了這個操作:

---------UNDONE(此處代碼待添加)

分配 IP 地址

     IP 地址是通過 InterNIC 分配給不同的組織和個人的。但是並非所有的 IP 地址都可以用來分配,其中也有一些私有的,或者說是預留出來的。

私有 IP

      一般 IP 地址都需要在 InterNIC 進行登記,但是如果你的系統沒有直接連接到 Internet,那麼久不需要全球唯一的地址,這個時候就可以使用私有 IP 地址來替代。

      RFC1597 就是描述怎麼分配私有 IP 地址的文檔。

      image

      最後到底選擇哪一種 IP 地址在很大的程度上取決於所需要建立的網絡數量,分離的網段以及每個網段上主機的數目。

保留 IP 地址

   保留 IP 地址的數量很多,在 RFC1166 文檔中有記錄。下面就是一個保留 IP 地址的實例:

image

操作 IP 地址

    inet_addr()函數的語法如下:

?
1
2
3
4
5
6
#include <sys/socket.h>
#include <neiinet/in.h>
 
#include <arpa/inet.h>
 
unsignedlong inet_addr(const char * string);

        這個函數使用 string 作爲輸入參數,並將這個點分十進制的 IP 地址轉換爲 32 位的二進制表示法,函數的返回值就是這個 32 位的二進制的網絡字節序。當然如果 string 不是一個有效的點分十進制 IP 地址,函數返回 INADDR_NONE。另外需要注意的是,當 inet_addr 函數返回 INADDR_NONE 的時候,它並沒有建立一個有效的 errno 值,所以當函數返回錯誤的時候,不要去測試 errno 的值。

       注意:

      在新程序中避免使用 inet_addr 函數,而應該使用 inet_aton 函數作爲代替。因爲對於 inet_addr 函數來說,即使輸入的參數是有效的 IP 地址:255.255.255.255,他的返回值仍然是 INADDR_NONE。

下面我們來說說 inet_aton 函數:

     inet_aton() 函數是將字符串形式的 IP 地址轉換爲網絡字節序的 32 位 IP 地址的改進形式。語法如下:

?
1
2
3
4
5
#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_ntoa() 函數

        有時候當用戶連接到你的服務器的時候,需要知道他的 IP 地址,系統提供了 inet_ntoa 函數將 32 位的二進制 IP 地址表示轉換爲點分十進制的字符串形式:

?
1
2
3
4
5
#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>
 
char* inet_ntoa(struct in_addr addr);

       需要注意的是inet_ntoa 函數的返回值直到下次調用前一直有效。所以如果在線程中使用 inet_ntoa 的時候,一定要確保每次只有一個線程調用本函數。否則一個線程的返回的結構可能被其他線程返回的結果所覆蓋。

接下來我們來看看inet_network() 函數。

        當我們需要用網絡掩碼將 IP 地址中的網絡位或者主機位提取出來的時候,如果能將點分十進制的 IP 地址轉換爲主機字節序的 32 位二進制 IP 地址形式就方便了,而 inet_network 函數的作用就是如此、語法如下:

?
1
2
3
4
5
#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>
 
unsignedlong inet_network(const char* addr);

      函數的輸入參數是存儲在字符串 addr 中的點分十進制 IP 地址,返回值是主機字節序的 32 位二進制地址,但是如果輸入參數不正確,返回值是 0xFFFFFFFF.

      以主機字節序的形式返回結果可以保證用戶安全的使用網絡掩碼,因爲如果返回值是網絡字節序的話,那麼不同的 CPU 平臺所使用的網絡掩碼和程序代碼就會有差異。

我們來看看inet_lnaof() 函數。

      函數 inet_lnaof 函數是將套接口地址中的 IP 地址(網絡字節序)轉換爲沒有網絡位的主機 ID(主機字節序),這個函數爲我們省去了很多的麻煩,因爲我們不需要對 IP 地址進行分類,再將主機位從 IP 地址中提取出來。函數語法如下:

      簡言之,IP 地址由 網絡地址 和 主機地址 組成,該函數可以去掉 IP 地址中的網絡地址,只保留主機地址。

?
1
2
3
4
5
#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>
 
unsignedlong inet_lnaof(struct in_addr addr);

下面的表提供了一些可以作爲inet_lnaof函數輸入的典型例子和返回值:

image

我們再來看看inet_netof() 函數

      inet_lnaof 函數返回的是主機 ID,而 inet_netof 函數返回的是網絡 ID,函數語法如下:

     去掉 IP 地址中的主機地址,只保留網絡地址,所以函數名爲 net of,反倒是 lna of 不好記憶

?
1
2
3
4
5
#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>
 
unsignedlong inet_netof(struct in_addr addr);

下表展示了一些例子:

image

      然後我們再來看看inet_makeaddr() 函數吧。根據之前的內容我們知道使用 inet_netof 函數和 inet_lnaof 函數,我們就可以把 IP 地址中的主機爲和網絡位分別提取出來,有時候我們還需要根據提取出來的主機位和網絡爲合併爲一個新的 IP 地址。這個時候我們就可以使用 inet_makeaddr 函數。

?
1
2
3
4
5
#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>
 
struct in_addr inet_makeaddr(int net , int host);



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章