纯粹copy,记录一下,讲的很细
这两个函数是随IPv6出现的新函数,对于IPv4地址和IPv6地址都适用。函数名中的p和n非别代表表达(presentation)和数值(numeric)。地址的表达格式通常是ASCII字符串,数值格式则是存放到套接字地址结构中的二进制值。函数如下:
-
-
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>头文件中有如下定义:
如果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);
-
}
-