Linux Socket學習--地址轉換函數


      一個IP地址是由小數點分開的十進制數表示的,我們稱之為點分十進制表示法。其中每一個十進制數代表一個字節的無符號數值(按照網絡字節序)因為每個字節都是無符號的8位數值,這就限制了每一個字節所能表示的范圍是0~255.

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()函數的語法如下:

#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函數輸入的典型例子和返回值:

image

我們再來看看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);

下表展示了一些例子:

image

然后我們再來看看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(此處代碼待添加)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM