网络编程IP地址转换相关函数介绍

1. sockaddr结构体和sockaddr_in结构体

/* 定义于头文件sys/socket.h */
struct sockaddr
{
  unsigned short sa_family; /*地址族*/
  char sa_data[14]; /* 14字节的协议地址,包含该socket的IP地址和端口号 */
};

/* 定义于头文件arpa/inet.h */
struct sockaddr_in
{
  short int sa_family; /*地址族*/
  unsigned short int sin_port; /*端口号*/
  struct in_addr sin_addr; /*IP地址*/
  unsigned char sin_zero[8]; /*填充0 以保持与struct sockaddr同样大小*/
};	

struct in_addr
{
  unsigned long int  s_addr; /* 32位IPv4地址,网络字节序 */
};

/**
 *sa_family:AF_INET  aIPv4协议; AF_INET6  àIPv6协议
 */

2. ip地址转换相关函数介绍

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/**
 * inet_aton()将点分十进制数的IP地址转换成为网络字节序的32位二进制数值.
 * 返回值:成功,则返回1,不成功返回0.
 */
int inet_aton(const char *straddr, struct in_addr *addrptr);
/**
 *inet_ntoa()将网络字节序的32位二进制数值转换为点分十进制的IP地址
 */
char *inet_ntoa(struct in_addr inaddr);
/**
 *inet_addr()功能与inet_aton相同,但是结果传递的方式不同。inet_addr()若成功则返回32位二进制的网络字节序地址。
 */
in_addr_t inet_addr(const char *straddr);

/**
 * 函数inet_pton跟inet_aton实现的功能类似,只是多了family参数,
 * 该参数指定为AF_INET,表示是IPv4协议,如果是AF_INET6,表示IPv6协议
 * 若函数成功,则返回1;若输入不是有效的格式,则函数返回0;若处理失败,函数返回-1
 */
int inet_pton(int family, const char *src, void *dst);
/**
 * 函数inet_ntop跟inet_ntoa类似,其中len表示表示转换之后的长度(字符串的长度)
 * 若函数处理成功,返回指向结果的指针;若函数处理失败,返回NULL
 */
const char *inet_ntop(int family, const void *src, char *dst, socklen_t len);

/** 两个函数的参数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     /* for IPv4 dotted-decimal */
#define INET6_ADDRSTRLEN 46   /* for IPv6 hex string */

/* POSIX 提供了 4 个函数(也可能是用宏来实现的),可以让本机字节序和网络字节序之间进行互转。它们分别是 */
#include <arpa/inet.h>
 
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
/* 其中,函数名字中的 h 表示 host(本机),n 表示 network(网络),而 l 表示要转换的数据是 4 字节,s 表示要转换的数据是 2 字节 */

3.使用例程

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

int main(int argc, char* argv[])
{
	char ip[] = "192.168.0.101";
	struct in_addr myaddr;
	/* inet_aton */
	int iRet = inet_aton(ip, &myaddr);
	if(0 == iRet)
	{
		fprintf(stderr,"ip error.\n");
		exit(1);     
	}
	printf("%x\n", myaddr.s_addr);

	/* inet_addr */
	printf("%x\n", inet_addr(ip));

	/* inet_pton */
	iRet = inet_pton(AF_INET, ip, &myaddr);
	printf("%x\n", myaddr.s_addr);

	myaddr.s_addr = 0xac100ac4;
   /* inet_ntoa */
	printf("%s\n", inet_ntoa(myaddr));

	/* inet_ntop */
	inet_ntop(AF_INET, &myaddr, ip, 16);
	puts(ip);
	return 0;
}

说明

即使系统还不支持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);

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值