1.利用域名获取IP地址
使用以下函数可以通过传递字符串格式的域名获取IP地址。
#include <netdb.h>
struct hostent * gethostbyname(const char * hostname); (成功返回 hostent结构体地址,失败时返回NULL指针)。
只要传递域名字符串,就会返回域名对应的IP地址。只是返回时,地址信息装入hostent结构体。此结构体如下。
struct hostent
{
char * h_name; //official name
char ** h_aliases; //alias list
int h_addrtype; //host address type
int h_length; //address length
char **h_addr_list; //address list
}
从上述结构体定义可以看出,不只返回IP信息,同时还连带着其他信息。各位不用想得太过复杂。域名转IP时只需
关注h_addr_list。下面简要说明上述结构体各成员。
------ h_name
该变量中存有官方域名(official domain name)。官方域名代表某一主页,但实际上,一些著名公司的域名并未用官方域名注册。
------h_aliases
可以通过多个域名访问同一主页。同一IP可以绑定多个域名,因此除官方域名外还可指定其他域名。这些信息可以通过h_aliases获得。
------h_addrtype
gethostbyname函数不仅支持IPv4,还支持IPv6。因此可以通过此变量获取保存在h_addr_list的IP地址的地址族信息。若是IPv4,则此变量存有AF_INET.
------h_length
保存IP地址长度。若是IPv4地址,因为是4个字节,则保存4;IPv6时,因为是16个字节,故保存16。
------h_addr_list
这是最重要的成员。通过此变量以整数形式保存域名对应的IP地址。另外,用户较多的网站有可能分配多个IP给同一域名,利用多个服务器进行负载均衡。此时同样可以通过此变量获取IP地址信息。
gethostbyname.c
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<netdb.h> void error_handling(char *message); int main(int argc,char *argv[]){ int i; struct hostent *host; if(argc!=2){ printf("Usage : %s<addr>\n",argv[0]); exit(1); } host = gethostbyname(argv[1]); if(!host) error_handling("gethost....error"); printf("official name: %s \n",host->h_name); for(i=0;host->h_aliases[i];i++) printf("Aliases %d: %s \n",i+1,host->h_aliases[i]); printf("Address type: %s \n",(host->h_addrtype==AF_INET)?"AF_INET":"AF_INET6"); for(i=0;host->h_addr_list[i];i++) printf("IP addr %d: %s \n",i+1,inet_ntoa(*(struct in_addr*)host->h_addr_list[i])); return 0; } void error_handling(char *message){ fputs(message,stderr); fputc('\n',stderr); exit(1); }
运行结果:gethostbyname.c
root@my_linux:/tcpip# gcc gethostbyname.c -o hostname
root@my_linux:/tcpip# ./hostname www.baidu.com
official name : www.a.shifen.com
Aliases 1 : www.baidu.com
Address type: AF_INET
IP addr 1 : 119.75.217.109
IP addr 2 : 119.75.218.70
#include <netdb.h>
struct hostent * gethostbyaddr(const char *addr, socklen_t len, int family);
成功时返回hostent结构体变量地址值,失败时返回NULL指针。
-------addr
含有IP地址信息的in_addr结构体指针。为了同时传递IPv4地址之外的其他信息,该变量的类型声明为char指针。
-------len
向第一个参数传递的地址信息的字节数,IPv4时为4,IPv6时为16。
-------family
传递地址族信息,IPv4时为AF_INET, IPv6为AF_INET6。
gethostbyaddr.c
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<netdb.h> void error_handling(char *message); int main(int argc,char *argv[]){ int i; struct hostent *host; struct sockaddr_in addr; if(argc!=2){ printf("Usage: %s <IP>\n",argv[0]); exit(1); } memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr = inet_addr(argv[1]); host = gethostbyaddr((char*)&addr.sin_addr,4,AF_INET); if(!host) error_handling("gethost... error!"); printf("Official name : %s \n",host->h_name); for(i=0;host->h_aliases[i];i++) printf("Aliases %d: %s \n",i+1,host->h_aliases[i]); printf("Address type: %s \n",(host->h_addrtype==AF_INET)?"AF_INET":"AF_INET6"); for(i=0;host->h_aliases[i];i++) printf("IP addr %d: %s \n",i+1,inet_ntoa(*(struct in_addr*)host->h_addr_list[i])); return 0; } void error_handling(char *message){ fputs(message,stderr); fputc('\n',stderr); exit(1); }