域名与IP信息解析
/etc/hosts 文件中有部分IP地址与域名主机名的信息
/etc/resolv.conf 里面有DNS服务器的IP地址
struct hostent
{
char *h_name; //主机的正式名字
char **h_aliases; //主机备选名称,以NULL结尾的链表
int h_addrtype; //返回地址的类型 有两种 AF_INET或 AF_INET6
int h_length; //地址长度 以字节为单位
char **h_addr_list; //主机网络地址,以NULL结尾的链表
#define h_addr h_addr_list[0]
};
通过域名返回主机信息
即通过www.baidu.com之类的域名得到相应的IP地址,别名之类的信息。
struct hostent *gethostbyname (__const char *__name) : 参数为主机域名
struct hostent *gethostbyname2 (__const char *__name, int __af) :参数2为地址协议类型
例子
#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)
{
int x, x2;
struct hostent *hp;
for(x = ; x < argc; ++x)
{
//从参数读取域名,返回主机信息
hp = gethostbyname(argv[x]);
if(!hp)
{
fprintf(stderr, "%s: host '%s'\n", hstrerror(h_errno), argv[x]);
continue;
}
printf("Host %s :\n", argv[x]);
printf("Officially:\t%s\n", hp->h_name); //官方名
fputs("Aliases:\t", stdout);
for(x2 = ; hp->h_aliases[x2]; ++x2) //其他名
{
if(x2)
fputs(", ", stdout);
fputs(hp->h_aliases[x2], stdout);
}
fputc('\n', stdout);
printf("Type:\t\t%s\n", hp->h_addrtype == AF_INET ? "AF_INET" : "AF_INET6");
//返回点分十进制IP地址
if(hp->h_addrtype == AF_INET)
{
for(x2 = ; hp->h_addr_list[x2]; ++x2)
printf("Address:\t%s\n", inet_ntoa(*(struct in_addr*)hp->h_addr_list[x2]));
}
putchar('\n');
}
return ;
}
通过域名和IP返回主机信息
struct hostent *gethostbyaddr (__const void *__addr, __socklen_t __len, int __type)
参数1:主机的IP地址的网络字节顺序。需要强制转换为char*
参数2:地址长度,IP地址长度为4
参数3:地址类型(IP地址类型为AF_INET)
例子
#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>
void main(int argc, const char **argv)
{
u_int addr;
struct hostent *hp;
char **p;
if(argc != )
{
printf("usage: %s IP-address\n", argv[]);
exit(EXIT_FAILURE);
}
//点分十进制转换为32位网络字节顺序
if((int)(addr = inet_addr(argv[])) == -)
{
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[]);
exit(EXIT_FAILURE);
}
for(p = hp->h_addr_list; *p != ; p++)
{
struct in_addr in;
char **q;
memccpy(&in.s_addr, *p, sizeof(in.s_addr));
printf("%s\t%s", inet_ntoa(in), hp->h_name);
for(q = hp->h_aliases; *q != ; q++)
printf("%s", *q);
printf("\n");
}
exit(EXIT_SUCCESS);
}
如上:好多查不到的。
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
协议无关,可适用于IPv4和IPv6
参数1:节点名,可以是主机名,也可以是二进制地址信息。IPV4为点分10进制,或是IPV6的16进制
参数2:十进制数的端口号或服务名,如ftp, http
参数3:调用者填写关于它想返回的信息类型。
参数4:存放返回addrinfo结构链表的指针地址信息。
void freeaddrinfo(struct addrinfo *ai) :getaddrinfo函数的res是动态获取的,需要用该函数返回给系统
const char *gai_strerror(int error) :查询错误信息