【原创】《Linux高级程序设计》杨宗德著 - 域名与IP信息解析
现实中需要实现IP地址与域名的转换,常见的解析方式为DNS方式。还可以使用/etc/hosts文件进入简单的解析,解析中采用的顺序由文件/etc/hosts.conf决定。如下所示
通过域名返回主机信息
struct_hostent
示例代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
extern int h_errno;
int main(int argc, char **argv)
{
char *ptr, **pptr;
char str[INET_ADDRSTRLEN];
struct hostent *hptr;
while (--argc> 0)
{
ptr = *++argv;
if ( (hptr = gethostbyname (ptr) ) == NULL)
{
printf("gethostbyname error for host: %s: %s",ptr, hstrerror (h_errno) );
continue;
}
printf ("official hostname: %s\n", hptr->h_name);
for (pptr=hptr->h_aliases; *pptr!= NULL; pptr++)
printf ("\talias: %s\n", *pptr);
switch (hptr->h_addrtype)
{
case AF_INET:
pptr = hptr->h_addr_list;
for ( ; *pptr != NULL; pptr++)
printf ("\taddress: %s\n",inet_ntop (hptr->h_addrtype, *pptr, str, sizeof (str)));
break;
default:
printf("unknown address type");
break;
}
}
exit(0);
}
运行结果
$ ./gethostbyname localhost
official hostname: localhost
alias: localhost.localdomain
alias: localhost4
alias: localhost4.localdomain4
alias: localhost.localdomain
alias: localhost6
alias: localhost6.localdomain6
address: 127.0.0.1
address: 127.0.0.1
通过域名和IP返回主机信息
参数1:addr 类型为&char,含义是指向一个数组的指针,该数组含有一个主机地址(如IP地址)信息。
参数2:len 类型为int,含义是一个整数,它给出地址长度(IP 地址长度是4);
参数3:type 类型为int,含义是一个整数,它给出地址类型(IP 地址类型为AF_INET)。
如果成功,gethostbyaddr返回一个hostent 结构的指针。如果发生错误,返回0。
示例代码(运行之后出现段错误)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
main(int argc, const char **argv)
{
u_int addr;
struct hostent *hp;
char **p;
if (argc != 2)
{
printf("usage: %s IP-address\n",argv[0]);
exit(EXIT_FAILURE);
}
if ((int) (addr = inet_addr (argv[1])) == -1)
{
printf("IP-address must be of the form a.b.c.d\n");
exit (EXIT_FAILURE);
}
hp=gethostbyaddr((char *) &addr, sizeof (addr), AF_INET);
if (hp == NULL)
{
printf("host information for %s no found \n", argv[1]);
exit (EXIT_FAILURE);
}
for (p = hp->h_addr_list; *p!=0;p++)
{
struct in_addr in;
char **q;
memcpy(&in.s_addr, *p, sizeof(in.s_addr));
printf("%s\t%s",inet_ntoa(in), hp->h_name);//在此句出现段错误,下面无法输出
printf("--- test ---\n");
for (q=hp->h_aliases;*q != 0; q++)
printf("%s", *q);
printf("\n");
}
exit (EXIT_SUCCESS);
}
getaddrinfo获取主机信息
此函数第1个参数node为节点名:可以是主机名,也可以是二进制地址信息,如果是IPV4则为点分10进制,或是IPV6的16进制。
此函数第2个参数servname:包含十进制数的端口号或服务名,例如(ftp,http)。
这两个参数并不是总需要,如果此函数只用于域名解析,第2个参数可以不需要,如果要直接绑定到某个地址,例如访问对方的FTP服务器,则需要指定该端口号。
此函数第3个参数hints:一个空指针或指向一个addrinfo结构的指针,由调用者填写关于它所想返回的信息类型。
此函数第4个参数res:此参数用来存放返回addrinfo结构链表的指针地址信息。
示例代码(运行之后出现段错误)
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
int main(int argc,char *argv[])
{
int rc;
char ipbuf[16];
struct addrinfo hints,*addr;
memset(&hints,0,sizeof(struct addrinfo));
hints.ai_family=AF_INET;
hints.ai_flags=AI_CANONNAME | AI_ADDRCONFIG;
if((rc=getaddrinfo(argv[1],argv[2],&hints,&addr))==0)
{
do{
printf("ip: %s\t",inet_ntop(AF_INET, &(((struct sockaddr_in*)addr->ai_addr)->sin_addr), ipbuf, sizeof(ipbuf)));//在此句出现段错误,下面无法输出
printf("host:%s\t",addr->ai_canonname);
printf("length:%d\t",addr->ai_addrlen);
printf("port:%d\n",ntohs(((struct sockaddr_in *)addr->ai_addr)->sin_port));
}while((addr=addr->ai_next)!=NULL);
return 0;
}
printf("%d\n",rc);
return 0;
}
原文链接
http://blog.csdn.net/geng823/article/details/42001475