工学1号馆

home

« | 返回首页 | »

Unix地址转换函数

By Wu Yudong on January 10, 2017

本文将介绍两组地址转换函数,在ASCII字符串与网络字节序的二进制值之间转换网际地址

1、inet_aton、inet_addr、inet_ntoa函数

int inet_aton(const char *strptr, struct in_addr *addrptr);
//返回:若字符串有效则为1,否则为0

inet_aton函数将strptr所指的C字符串转换成一个32位的网络字节序二进制值,并通过指针addrptr来存储

in_addr_t inet_addr(const char *strptr);
//返回:若字符串有效则为32位二进制网络字节序的IPv4地址,否则为INADDR_NONE

inet_addr有缺陷,现已被废弃,使用inet_aton替换。

char *inet_ntoa(struct in_addr inaddr);
//返回:指向一个点分十进制数串的指针

inet_ntoa函数返回值所指向的字符串驻留在静态内存中,这意味着这个函数是不可重入的

2、inet_pton、inet_ntop函数

这两个函数对ipv4与ipv6都适用,其中的n表示数值(存放到套接字地址结构中的二进制值),p表示表达式(ASCII字符串)

#include <arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);
//返回:若输入不是有效的表达式格式则为0,若出错则为-1

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
//返回:若成功则为指向结果的指针,若出错则为NULL

这两个函数进行相反的转换,len 参数是目标存储单元的大小,以免该函数溢出其调用者的缓冲区,在<netinet/in.h>中有下面的定义:

#define INET_ADDRSTRLEN 16    //针对ipv4的点分十进制
#define INET6_ADDRSTRLEN 46    //针对ipv6的十六进制字符串

下面给出只支持ipv4的inet_pton的简化版本:

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 1;
		}
		return 0;
	}
	errno = EAFNOSUPPORT;
	return -1;
}

下面给出只支持ipv4的inet_ntop的简化版本:

int inet_pton(int family, const char *strptr, void *addrptr)
{
	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;
}

 

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)