当前位置: 首页 > news >正文

【Linux C | 网络编程】gethostbyname 函数详解及C语言例子

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 gethostbyname 函数 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
⏰发布时间⏰:

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、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 <netdb.h>
    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 的值对应的字符串。

✨2.2 hostent 结构体说明

hostent结构体定义在 netdb.h 文件中,内容如下:

struct hostent {char  *h_name;            /* official name of host */char **h_aliases;         /* alias list */int    h_addrtype;        /* host address type */int    h_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_addrh_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 <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>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;char	str[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,以及提供使用例子。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考资料:
1、Linux的man手册
2、《Unix网络编程卷1》

相关文章:

  • 人工智能与网络安全
  • Android 监听网络状态变化
  • POST参数里加号+变成空格的问题处理
  • C++内存管理【new 和 delete 关键字】笔记
  • 【Leetcode】938. 二叉搜索树的范围和
  • 【QT+QGIS跨平台编译】之五十五:【QGIS_CORE跨平台编译】—【qgsmeshcalcparser.cpp生成】
  • 【C#】SixLabors.ImageSharp和System.Drawing两者知多少
  • 刷题 16 前缀和
  • 常用网络协议的学习
  • 项目实战:Qt监测操作系统物理网卡通断v1.1.0(支持windows、linux、国产麒麟系统)
  • YOLOv9图像标注和格式转换
  • 通过配置数据库事件(Event)来实现定时导出 MySQL 数据库
  • XSS简介及xsslabs第一关
  • Linux 学习笔记(1-3)
  • 【Spring】回顾反射机制
  • 【笔记】你不知道的JS读书笔记——Promise
  • Akka系列(七):Actor持久化之Akka persistence
  • Java方法详解
  • JS+CSS实现数字滚动
  • js学习笔记
  • Making An Indicator With Pure CSS
  • rc-form之最单纯情况
  • Redis在Web项目中的应用与实践
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • Spring Cloud中负载均衡器概览
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 给初学者:JavaScript 中数组操作注意点
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 我有几个粽子,和一个故事
  • 学习Vue.js的五个小例子
  • 原生JS动态加载JS、CSS文件及代码脚本
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2.2w字)前端单元测试之Jest详解篇
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (floyd+补集) poj 3275
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (LeetCode) T14. Longest Common Prefix
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (翻译)terry crowley: 写给程序员
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (十) 初识 Docker file
  • (四) 虚拟摄像头vivi体验
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)Oracle 9i 数据库设计指引全集(1)
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET Core跨平台微服务学习资源
  • .net 反编译_.net反编译的相关问题
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)