通过域名解析对应的IP地址
接手项目之后,确认采用UDP模式和公司的服务器进行数据的交互。由于公司服务器的IP不是固定不变的,但是域名是确定的,因此,需要根据公司的服务器域名解析出对应的IP地址之后,创建对应的UDP通讯。
通过域名解析IP的源码
#include<netdb.h>
#include<sys/socket.h>
void HostnameToIP(char *hostname,char *ip)
{
struct hostent *he; //定义一个hostent类型的结构体
struct in_addr **addr_list; //定义一个指向in_addr结构体的指针
int i;
if((he = gethostbyname(hostname)) == NULL) //通过域名获取到对应IP,将结果保存在he结构体中
{
printf("根据域名解析IP出错!\n");
return;
}
addr_list = (struct in_addr **)he->h_addr_list; //将he结构体中对应的IP地址放入addr_list中
for(i=0;addr_list[i] != NULL;i++) //将addr_list中的IP地址放入Ip中
{
strcpy(ip,inet_ntoa(*addr_list[i]));
return;
}
return;
}
void main()
{
char hostname[20] = "www.google.cn"; //定义google的域名
char ip_google[20]; //定义字符串用于保存google的IP
HostnameToIP(hostname,ip_google); //通过google的域名解析出对应Ip地址保存在IP_google中
printf("解析出的IP=%s\n",ip_google); //打印出解析出的IP地址
return;
}
源码解析
函数原型:
struct hostent *gethostbyname(const char *name);
这个函数的传入值是域名或者主机名,如“www.google.cn”等.传出值,是一个hostent的结构体。如果函数调用失败,则返回NULL。
返回hostent结构体类型的指针:
struct hostent {
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
}
#define h_addr h_addr_list[0]
hostent->h_name
表示的是主机的规范名。例如www.google.com的规范名其实是www.l.google.com。
hostent->h_aliases
表示的是主机的别名.www.google.com就是google他自己的别名。有的时候,有的主机可能有好几个别名,这些,其实都是为了易于用户记忆而为自己的网站多取的名字。
hostent->h_addrtype
表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是pv6(AF_INET6)
hostent->h_length
表示的是主机ip地址的长度
hostent->h_addr_lisst
表示的是主机的ip地址,注意,这个是以网络字节序存储的。千万不要直接用printf带%s参数来打这个东西,会有问题。所以到真正需要打印出这个IP的话,需要调用inet_ntop()。
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
这个函数,是将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。返回指向dst的一个指针。如果函数调用错误,返回值是NULL。