inet_pton 和 inet_ntop 等函数

inet_pton和inet_ntop是适用于IPv4和IPv6的函数,用于处理包含0字节的IP地址,避免了使用str开头的函数导致的问题。这些函数分为两类,一组以b开头源自4.2BSD,另一组以mem开头源自ANSI标准。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

inet_pton 和inet_ntop对IPv4和IPv6都适用

<arpa/inet.h>头文件中的声明如下:

 int inet_pton (int __af, const char *__restrict __cp, void *__restrict __buf)

const char *inet_ntop (int __af, const void *__restrict __cp, char *__restrict __buf, size_t socklen_t__len)

man

SYNOPSIS
       #include <arpa/inet.h>

       int inet_pton(int af, const char *src, void *dst);

DESCRIPTION
       This  function converts the character string src into a network address
       structure in the af address family, then  copies  the  network  address
       structure to dst.  The af argument must be either AF_INET or AF_INET6.

//              inet_ntop             
NAME
       inet_ntop - convert IPv4 and IPv6 addresses from binary to text form

SYNOPSIS
       #include <arpa/inet.h>

       const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

DESCRIPTION
       This  function  converts  the  network  address structure src in the af address family into a character string.  The resulting string is copied to the buffer pointed to by dst, which must be a non-null pointer.  The caller specifies the number of bytes available in this  buffer  in  the argument size.
/*size 为目标储存单元的大小,即点分十进制的长度或冒号16进制的长度,为了有助于指定这个大小,在`<netinet/in.h>`中有如下定义:*/
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46

与书中有些出入,不过不影响。

字节操纵函数

为什么要这些函数?

因为有些字段(IP地址)可能包含值为0的字节,但却不是C字符串。不能用str开头的函数处理。

这些函数分为两类:

以b开头的第一组函数起源于4.2BSD:

       #include <strings.h>
       //bzero - write zero-valued bytes
       void bzero(void *s, size_t n);

       //bcopy - copy byte sequence
       void bcopy(const void *src, void *dest, size_t n);

       // bcmp - compare byte sequences
       int bcmp(const void *s1, const void *s2, size_t n);

//const限定被修饰的指针所指向的内容不能被函数改变 

man

 The bzero()  function sets the first n bytes of area starting at s to zero (bytes containing '\0').

The  bcopy()  function  copies n bytes from src to dest.  The result is correct, even when both areas overlap.

DESCRIPTION
       The bcmp() function compares the two byte sequences s1 and s2 of length n each.  If they are equal, and in particular  if  n  is  zero,  bcmp() returns 0.  Otherwise, it returns a nonzero result.

RETURN VALUE
       The  bcmp()  function returns 0 if the byte sequences are equal, other-wise a nonzero result is returned.

以mem(memory)开头的第二组函数起源于ANSI标准:

#include <string.h>
//memset - fill memory with a constant byte
void *memset(void *s, int c, size_t n);

//memcpy - copy memory area
void *memcpy(void *dest, const void *src, size_t n);

//memcmp - compare memory areas
int memcmp(const void *s1, const void *s2, size_t n);

man

//memset
The  memset()  function  fills  the  first  n  bytes of the memory area pointed to by s with the constant byte c.
//memcpy
The  memcpy()  function  copies  n bytes from memory area src to memory area dest.  The memory areas must not overlap.  Use memmove(3)  if  the memory areas do overlap.
//memcmp
DESCRIPTION
       The  memcmp()  function compares the first n bytes (each interpreted as unsigned char) of the memory areas s1 and s2.

RETURN VALUE
       The memcmp() function returns  an  integer  less  than,  equal  to,  or greater than zero if the first n bytes of s1 is found, respectively, to be less than, to match, or be greater than the first n bytes of s2.

       For a nonzero return value, the sign is determined by the sign  of  the difference  between  the  first  pair of bytes (interpreted as unsigned char) that differ in s1 and s2.
      If n is zero, the return value is zero.

未完

inet_ptoninet_ntop是用于IP地址转换的两个函数,分别用于将点分十进制的IPv4地址转换成网络字节序的二进制形式将网络字节序的二进制形式的IPv4地址转换成点分十进制形式。 下面是它们的实现: ```c #include <arpa/inet.h> #include <string.h> int inet_pton(int af, const char *src, void *dst) { if (af == AF_INET) { struct in_addr addr; if (inet_aton(src, &addr) == 0) { return 0; } memcpy(dst, &addr.s_addr, sizeof(addr.s_addr)); return 1; } else if (af == AF_INET6) { struct in6_addr addr; if (inet_pton(AF_INET6, src, &addr) == 0) { return 0; } memcpy(dst, &addr, sizeof(addr)); return 1; } return -1; } const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { if (af == AF_INET) { struct in_addr addr; memcpy(&addr.s_addr, src, sizeof(addr.s_addr)); if (inet_ntop(AF_INET, &addr, dst, size) == NULL) { return NULL; } return dst; } else if (af == AF_INET6) { struct in6_addr addr; memcpy(&addr, src, sizeof(addr)); if (inet_ntop(AF_INET6, &addr, dst, size) == NULL) { return NULL; } return dst; } return NULL; } ``` 对于inet_pton函数,我们首先判断地址族af是否为IPv4或IPv6,然后根据不同的地址族调用inet_aton或inet_pton进行转换。如果转换成功,则将转换后的二进制地址复制到dst指针所指向的内存中,并返回1;否则返回0表示转换失败。 对于inet_ntop函数,我们同样首先判断地址族af是否为IPv4或IPv6,然后根据不同的地址族调用inet_ntop进行转换。如果转换成功,则将转换后的点分十进制地址复制到dst指针所指向的内存中,并返回dst指针;否则返回NULL表示转换失败。需要注意的是,目标内存大小size应该足够存放转换后的地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值