inet_pton函式和inet_ntop函式的用法及簡單實現
阿新 • • 發佈:2019-01-11
這兩個函式是隨IPv6出現的新函式,對於IPv4地址和IPv6地址都適用。函式名中的p和n非別代表表達(presentation)和數值(numeric)。地址的表達格式通常是ASCII字串,數值格式則是存放到套接字地址結構中的二進位制值。函式如下:
#include<arpa/inet.h> int inet_pton(int family, const char *strptr, void *addrptr); 返回:若成功則為1,若輸入不是有效的表達格式則為0,若出錯則為-1 const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len); 返回:若成功則為指向結果的指標, 若出錯則為NULL
這兩個函式的family引數既可以是AF_INET,也可以是AF_INET6。如果以不被支援的地址族作為family的引數,這兩個函式就都返回一個錯誤,並將errno置為EAFNOSUPPORT。
第一個函式嘗試轉換由strptr指標所指的字串,並通過addrptr指標存放二進位制結果。若成功則返回1,否則如果對所指定的family而言輸入的字串不是有效的表示式,那麼值為0。
inet_ntop進行相反的轉換,從數值格式(addrptr)轉換到表達格式(strptr)。len引數是目標儲存單元的大小,以免該函式溢位其呼叫者的緩衝區。為有助於指定這個大小,在<netinet/in.h>標頭檔案中有如下定義:
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
如果len太小,不足以容納表示式結果(包括結尾的空字元),那麼返回一個空指標,並置errno為ENOSPC。
inet_ntop函式的strptr引數不可以是一個空指標。呼叫者必須為目標儲存單元分配記憶體並指定其大小。呼叫成功時,這個指標就是該函式的返回值。
即使系統還不支援IPv6,也可以採取下列措施開始使用這些新函式,即用程式碼
inet_pton(AF_INET, cp, &foo.sin_addr); 代替程式碼 foo.sin_addr.s_addr = inet_addr(cp); 再用程式碼 char str[INET_ADDRSTRLEN]; ptr = inet_ntop(AF_INET, &foo.sin_addr, str, sizeof(str)); 代替程式碼 ptr = inet_ntoa(foo.sin_addr);
下面給出只支援IPv4的inet_pton函式的簡單定義和只支援IPv4的inet_ntop函式的簡化版本。
int inet_pton(int family, const char *strptr, void *addrptr)
{
if(family == AF_INET) {
struct in_addr in_val;
if (inet_aton(strptr, &in_val)) {
memcpy(addrptr, &in_val, sizeof(struct in_addr));
return (0);
}
}
errno = EAFNOSUPPORT;
return (-1);
}
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t lne)
{
const u_char *p = (const u_char *) addrptr;
if(family == AF_INET) {
char temp[INET_ADDRSTRLEN];
snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
if (strlen(temp) >= len){
errno = ENOSPC;
return (NULL);
}
strcpy(strptr, temp);
return (strptr);
}
errno = EAFNOSUPPORT;
return (NULL);
}