inet_aton、inet_addr、inet_ntoa 、inet_ntop、inet_pton

ip地址的转换总是让人头大,整合到一起看吧

1、inet_addr:点分十进制的IP地址字符串转化为unsigned int(网络字节序)

#include <arpa/inet.h>

struct in_addr
{
    in_addr_t s_addr;
}

//in_addr_t 一般为 32位的unsigned int,其字节顺序为网络顺序network byte ordered

//可以理解为就是转为unint32类型
in_addr_t inet_addr(const char* strptr);

in_addr myaddr;
myaddr.s_addr = inet_addr("172.18.29.32");

2、inet_aton:将一个字符串IP地址转换为一个32位的网络序列IP地址。如果这个函数成功,函数的返回值非零,如果输入地址不正确则会返回零。

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

完整描述:
int inet_aton(const char *string, struct in_addr*addr);

struct sockaddr_in
{
    /*Address family一般来说AF_INET(地址族)PF_INET(协议族)*/
    short sin_family;

    //Port number(必须要采用网络数据格式,普通数字可以用htons()函数转换
    unsigned short sin_port;

    /*IP address in network byte order(Internet address)*/
    struct in_addr sin_addr;

    /*Same size as struct sockaddr没有实际意义,只是为了跟SOCKADDR结构在内存中对齐*/
    unsigned char sin_zero[8];
};

struct sockaddr_in s_addr; 
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(8000); 
inet_aton("127.0.0.1", &s_addr.sin_addr);

3、inet_ntoa:将网络地址转换成“.”点隔的点分十进制IP地址字符串格式

#include <arpa/inet.h>
char *inet_ntoa(struct in_addr in);
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
	struct in_addr addr1,addr2;
	addr1.s_addr = inet_addr("10.67.68.60");
	addr2.s_addr = inet_addr("10.1.1.10");

	printf("%s %s\n", inet_ntoa(addr1), inet_ntoa(addr2));
	printf("addr1: %s\n", inet_ntoa(addr1));
	printf("addr2: %s\n", inet_ntoa(addr2));
	return 0;
}

10.67.68.60 10.67.68.60
addr1: 10.67.68.60
addr2: 10.1.1.10

inet_ntoa返回一个char *,而这个char *的空间是在inet_ntoa里面静态分配的,所以inet_ntoa后面的调用会覆盖上一次的调用。第一句printf的结果只能说明在printf里面的可变参数的求值是从右到左的,仅此而已。

4、inet_ntop:用于将网络字节序的IPv4或IPv6地址转换成文本表示形式(即点分十进制表示法)。它是inet_ntoa函数的升级版本,它支持IPv4和IPv6地址,而inet_ntoa只支持IPv4地址。

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

它有四个参数:

  1. af:地址族,可以是AF_INET(IPv4)或AF_INET6(IPv6)

  2. src:指向指定地址族的IP地址的指针( in_addr)

  3. dst:指向存储文本表示形式的IP地址的缓冲区的指针(字符串)

  4. size:缓冲区大小

#include <stdio.h>
#include <arpa/inet.h>

int main()
{
	char ip_addr[32] = {0};
	struct in_addr st_ip;
	inet_pton(AF_INET, "10.67.68.80", &st_ip);
	inet_ntop(AF_INET, &st_ip, ip_addr, sizeof(ip_addr));
	printf("ip_addr: %s\n", ip_addr);
	return 0;
}

ip_addr: 10.67.68.80

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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_atoninet_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、付费专栏及课程。

余额充值