如何将域名转换为ip

一,前言
这篇文章主要讲述了如何将域名如“www.baidu.com”转换为类似“127.0.0.1”的IP地址,转换的过程主要使用了DNS协议相关的内容,但我们的重点并不是这里,有兴趣的可自行了解。我主要讲的是如何使用,主要包括以下几个内容:
1,hostent结构体
2,gethostbyname函数的用法
以上内容全都是在Linux环境里。

二,详细内容
1,hostent结构体
struct hostent
{
char * h_name;
char ** alias_list;
int h_addrtype;
int h_length;
char ** h_addr_list;
};
h_name:主机的规范名,如“www.baidu.com”,它的规范名其实是“www.a.shifen.com”,这一点可以通过ping命令得到。

这里写图片描述

alisa_list:这是主机的别名,它是一个二级指针,这是因为主机的别名有可能有好几个。

h_addrtype:指主机的IP地址类型,到底是IPV4还是IPV6。

h_length:指主机的IP地址长度。

h_addr_list:它也是一个二级指针,它主要指向主机IP地址数组的指针,这是因为一个主机它的IP地址可能有多个,这也不难理解,如果你有多个网卡,你的IP地址自然也是有多个,但它们实际却都是指向你的。
另外还有一个定义h_addr它是一个指针,它指向h_addr_list[0],其实大部分时候我们只需要一个IP地址就够了,所以没必要知道那么多它的别名,需要注意的是这里的IP都是二进制的形式,它不是我们常见的点分十进制形式,所以如果直接打印可能会带来疑惑。
2,gethostbyname函数
它所在头文件:
sys/socket.h
netdb.h
//这里之所以不用include那种形式是因为带上‘#’markdown字体将会变大,所以见谅。
函数原型:
hosten* gethostbyname(const char* hostname);
它返回一个结构体的指针,如果没有找到“hostname”,将会返回NULL。
接下来请看其使用:
2.1

#include<stdio.h>
#include<netdb.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char* argv[])
 {
 char* ptr,**pptr;
 struct hostent* hptr;
 char str[32];
 ptr=argv[1];
 if((hptr=gethostbyname(ptr))==NULL)
     {
      perror("gethostbyname");
      return -1;
     }
 printf("offical hostname:%s\n",hptr->h_name);
 for(pptr=hptr->h_aliases;*pptr!=NULL;pptr++)
 {
  printf("alias:%s\n",*pptr);
 }
pptr=hptr->h_addr_list;
 for(;*pptr!=NULL;pptr++)
 {
  printf("address:%s\n",inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));
 }
 return 0;
 }

上述代码的功能主要是用户给定一个域名,然后打印出它的别名,以及它的所有IP地址。

其中inet_ntop函数是将网络字节序转为点分十进制形式。
请看运行结果:

这里写图片描述
经过编译之后,我们发现淘宝网的正式名称其实是那一长串,而它的别名才是我们熟悉的那个。
2.2 h_addr的使用
我们已经知道,h_addr是一个域名众多IP地址中的一个,但是因为它是二进制形式,所以在使用时是可以直接使用的,如下:

#include<stdio.h>
#include<netdb.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char* argv[])
 {
 //char* ptr,**pptr;
 struct hostent* hptr;
 //char str[32];
 ptr=argv[1];
 if((hptr=gethostbyname(ptr))==NULL)
     {
      perror("gethostbyname");
      return -1;
     }
/* printf("offical hostname:%s\n",hptr->h_name);
 for(pptr=hptr->h_aliases;*pptr!=NULL;pptr++)
 {
  printf("alias:%s\n",*pptr);
 }
pptr=hptr->h_addr_list;
 for(;*pptr!=NULL;pptr++)
 {
  printf("address:%s\n",inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));

 }*/
 struct in_addr myaddr;
 memcpy(&myaddr.s_addr,hptr->h_addr,sizeof(hptr->h_addr));
 printf("address:%s\n",inet_ntoa(myaddr));
 //printf("address:%s\n",inet_ntop(hptr->h_addrtype,ptr,str,sizeof(str)));
 return 0;
 }


结果:
这里写图片描述

三,结论
遇到困难,搞了半天才弄明白了,记录下来,方便自己,也留给需要的有缘人吧,综上。

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux C 语言中,可以使用 getaddrinfo 函数将域名转换IP 地址。 具体实现步骤如下: 1. 引入头文件: ``` #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> ``` 2. 定义 getaddrinfo() 函数所需的结构体: ``` struct addrinfo hints, *res; int status; char ipstr[INET6_ADDRSTRLEN]; ``` 3. 初始化 hints 结构体: ``` memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // AF_INET 或 AF_INET6 均可 hints.ai_socktype = SOCK_STREAM; // TCP ``` 4. 调用 getaddrinfo() 函数: ``` status = getaddrinfo("www.example.com", NULL, &hints, &res); ``` 其中 "www.example.com" 是需要转换域名。 5. 遍历返回的地址列表,并将其转换IP 地址: ``` struct addrinfo *p; void *addr; for(p = res; p != NULL; p = p->ai_next) { if (p->ai_family == AF_INET) { // IPv4 struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; addr = &(ipv4->sin_addr); } else { // IPv6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; addr = &(ipv6->sin6_addr); } // 将 IP 地址转换为字符串 inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr); } ``` 其中,inet_ntop() 函数将 IP 地址转换为字符串形式,ipstr 变量即为转换后的 IP 地址。 6. 释放内存: ``` freeaddrinfo(res); ``` 完整代码如下: ``` #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { struct addrinfo hints, *res; int status; char ipstr[INET6_ADDRSTRLEN]; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; status = getaddrinfo("www.example.com", NULL, &hints, &res); if (status != 0) { fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status)); exit(1); } struct addrinfo *p; void *addr; for(p = res; p != NULL; p = p->ai_next) { if (p->ai_family == AF_INET) { // IPv4 struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; addr = &(ipv4->sin_addr); } else { // IPv6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; addr = &(ipv6->sin6_addr); } inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr); printf("IP address: %s\n", ipstr); } freeaddrinfo(res); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值