IP地址与域名之间的转换(Linux + GCC)

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



2.利用IP地址获取域名


#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);
}



你可能感兴趣的:(gcc,C语言,Linux网络编程,套接字编程,TCPIP网络编程)