《Linux环境下C编程指南(第二版)》p257 ip地址转换函数
在TCP/IP网络上,使用ASCII地址,即使用以.隔开的4个十进制的数表示。但是在套接字地址中则使用32位的网络字节序的二进制数值。要实现两者之间的转换,就要用到以下三个函数:
in_addr_t inet_addr(const char* straddr);
成功时返回32位二进制的网络字节序地址,如果出错返回INADDR_NONE
INADDR_NONE是一个常数,是一个不存在的IP地址,一般将这个常数定义为255.255.255.255,用二进制表示再转成有符号数就是-1
int inet_aton(const char *straddr, struct in_addr *addrp);
char* inet_ntoa(struct in_addr inaddr);
其中,inet_aton是将ASCII地址转换成网络字节序的32位二进制值,输入的ASCII数放在参数straddr中,作为返回结果的整数放在参数addrp中。返回1表示转换成功,如果返回0则转换不成功。
函数inet_ntoa的功能正好相反,它将32位二进制地址转换成ASCII地址,调用的结果作为函数返回值返回给调用它的函数,返回ASCII地址,如果转换不成功,则返回NULL。
举例:
如果有struct sockaddr_in类型的变量sin,想将IP地址"162.105.12.145"存储到其中,可以使用函数inet_addr()
sin.sin_addr.s_addr = inet_addr("162.105.12.145");
如果有struct in_addr,要按照ASCII格式打印,可以使用函数inet_ntoa()
printf("%s", inet_ntoa(ina.sin_addr));
这条语句会打印IP地址
附上相关数据结构
#include <netinet/in.h>
struct in_addr
{
in_addr_t s_addr; /*32位IP地址,网络字节序*/
}
IPv4套接字地址结构:
struct sockaddr_in
{
uint8 sin_len;
sa_family_t sin_family;
in_port_t sin_port; /*16位端口号,网络字节序*/
struct in_addr sin_addr;
char sin_zero[8] /*备用的域,未使用,为了与struct sockaddr保持同样的字节数*/
}