博客主页:https://blog.csdn.net/wkd_007
博客内容:嵌入式开发、Linux、C语言、C++、数据结构、音视频
本文内容:介绍 gethostbyname 函数
金句分享:你不能选择最好的,但最好的会来选择你——泰戈尔
⏰发布时间⏰:2024-02-29 14:55:06
本文未经允许,不得转发!!!
目录
- 一、概述
- 二、gethostbyname 函数
- ✨2.1 gethostbyname 函数介绍
- ✨2.2 hostent 结构体说明
- ✨2.3 gethostbyname 函数的工作原理
- 三、gethostbyname 函数使用例子
- 四、总结
一、概述
在网络编程中,可能出现这样的情况,你只知道某个服务器的主机名或域名,但不知道其具体的ip地址是什么。例如,你可能知道百度的网址是:www.baidu.com
,但不知道其IP地址具体是什么。而gethostbyname可以让我们知道某个网址对应的IP地址,gethostbyname函数是Linux系统中用于获取主机名对应IP地址的函数之一。
使用域名的好处:
1、客户端中直接使用 IP 地址会有很大的弊端,一旦 IP 地址变化(IP 地址会经常变动),客户端软件就会出现错误。
2、名字相对于点分十进制的ip更好记忆。特别是IPv6的ip地址更难记忆。
本文将详细介绍 gethostbyname 函数,并且使用C语言例子演示 gethostbyname 函数的使用。
二、gethostbyname 函数
✨2.1 gethostbyname 函数介绍
1、函数原型:
#include extern int h_errno;struct hostent *gethostbyname(const char *name);
2、函数描述:
gethostbyname()
函数为给定的主机名返回hostent
类型的结构。这里的name
要么是主机名,要么是标准点表示法的IPv4地址,要么是冒号表示法的IPv6地址(可能还有点)。
如果name
是IPv4或IPv6地址,则不执行任何查找,gethostbyname()
只是将name
复制到h_name
字段中,并将其等效结构in_addr
复制到返回的主机结构的h_addr_list[0]
字段中。
如果名称不是以句点结尾,并且设置了环境变量HOSTALIASES,则将首先搜索HOSTALIASES指向的别名文件的名称。除非名称以句点结尾,否则将搜索当前域及其父域。3、参数、返回值
- 参数:name,为主机名,也就是域名。使用该函数时,只要传递域名字符串,就会返回域名对应的 IP 地址。返回的地址信息会装入
hostent
结构体。 - 返回值:成功返回
hostent
结构体指针(看下一小节),失败返回NULL,且设置h_errno
变量。注意,出错时不设置errno
变量,而是设置h_errno
变量,且提供了hstrerror
函数来获取h_errno
的值对应的字符串。
- 参数:name,为主机名,也就是域名。使用该函数时,只要传递域名字符串,就会返回域名对应的 IP 地址。返回的地址信息会装入
✨2.2 hostent 结构体说明
hostent
结构体定义在 netdb.h
文件中,内容如下:
struct hostent {char*h_name;/* official name of host */char **h_aliases; /* alias list */inth_addrtype;/* host address type */inth_length;/* length of address */char **h_addr_list; /* list of addresses */}#define h_addr h_addr_list[0] /* for backward compatibility */
结构体字段说明:
h_name
:官方域名(Official domain name)。官方域名代表某一主页,但实际上一些著名公司的域名并未用官方域名注册。h_aliases
:主机的别名数组,以NULL指针结束,可以通过多个域名访问同一主机。同一 IP 地址可以绑定多个域名,因此除了当前域名还可以指定其他域名。h_addrtype
:地址的类型;按照DNS的说法,gethostbyname只能返回IPv4(AF_INET
)的地址。h_length
:保存IP地址长度。h_addr_list
:指向主机IP地址的指针数组(按网络字节顺序),以NULL指针结束。需要通过inet_ntop
函数转换。h_addr
:h_addr_list
中第一个地址。
✨2.3 gethostbyname 函数的工作原理
gethostbyname
函数的主要功能是根据输入的主机名获取相应的IP地址信息。它通过查询本地主机上的DNS解析器来查找主机名对应的IP地址,并返回一个struct hostent
类型的结构体,其中包含有关主机名和IP地址的信息。下面是gethostbyname
函数的基本工作流程:
- 1、接受一个主机名作为参数。
- 2、首先检查本地主机上的hosts文件,如果找到匹配的主机名,则返回相应的IP地址。
- 3、如果未找到匹配项,gethostbyname会向DNS服务器发送查询请求,以获取主机名对应的IP地址。
- 4、最终,函数返回一个包含主机名和IP地址信息的struct hostent结构体。
一般,在Linux系统中存在一个静态主机文件/etc/hosts
。而文件/etc/resolv.conf
通常包含本地名字服务器主机的IP地址。
三、gethostbyname 函数使用例子
// gethostbyname_sample.c#include #include #include #include extern int h_errno; int main(int argc, char **argv){if (argc != 2) {printf("Use example: %s www.google.com\n", *argv);return -1;} char*name = argv[1], **pptr;charstr[INET_ADDRSTRLEN];struct hostent *hptr = gethostbyname(name);if (hptr == NULL) {printf("gethostbyname error for host: %s: %s\n", name, hstrerror(h_errno));return -1;}printf("\tofficial: %s\n", hptr->h_name);//输出主机的规范名 for (pptr=hptr->h_aliases; *pptr!=NULL; pptr++) {printf("\ttalias: %s\n", *pptr); //输出主机的别名} //输出ip地址switch (hptr->h_addrtype) {case AF_INET:for (pptr=hptr->h_addr_list; *pptr!=NULL; pptr++) {printf("\taddress: %s\n",inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));}break;default:printf("unknown address type\n");break;} return 0;}
运行结果:
下面是分别查询www.baidu.com
(百度)、www.goolge.com
(谷歌)、localhost
(本地主机名)的打印结果。
nslookup
命令是Ubuntu自带的查询域名的工具,下面是使用nslookup
命令的打印,可以看到获取的主要内容和上面一致:
四、总结
本文主要介绍将域名转换为IP地址的函数gethostbyname,以及提供使用例子。
通过以上介绍,我们详细了解了Linux系统中gethostbyname函数的工作原理、使用场景以及如何在C语言中使用该函数。gethostbyname函数在网络编程中起着重要作用,能够帮助我们实现主机名到IP地址的转换,从而支持各种网络通信功能。希望本文能够帮助您更好地理解和应用gethostbyname函数。
如果文章有帮助的话,点赞、收藏⭐,支持一波,谢谢
参考资料:
1、Linux的man手册
2、《Unix网络编程卷1》