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

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

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

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

目录

  • 🎄一、概述
  • 🎄二、getaddrinfo 函数
    • ✨2.1 getaddrinfo 函数介绍
    • ✨2.2 struct addrinfo 结构体说明
  • 🎄三、gai_strerror、freeaddrinfo 函数
    • ✨3.1 gai_strerror 函数介绍
    • ✨3.2 freeaddrinfo 函数介绍
  • 🎄四、getaddrinfo 函数使用例子
  • 🎄五、总结


在这里插入图片描述

🎄一、概述

前面介绍过域名和IP地址之间转换的两个函数:gethostbynamegethostbyaddr,但是这两个函数仅仅支持IPv4。本文再介绍一个可支持 IPv4 和 IPv6 的函数getaddrinfo,该函数可以处理名字到地址以及服务到端口这两种转换。


在这里插入图片描述

🎄二、getaddrinfo 函数

✨2.1 getaddrinfo 函数介绍

  • 1、函数原型:

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    int getaddrinfo(const char *node, const char *service,const struct addrinfo *hints, struct addrinfo **res);
    void freeaddrinfo(struct addrinfo *res);
    const char *gai_strerror(int errcode);
    
  • 2、函数描述:
    getaddrinfo函数根据给定的主机名和服务名,返回一个struct addrinfo结构链表,每个struct addrinfo结构都包含一个互联网地址。getaddrinfo函数将gethostbynamegetservbyname函数提供的功能组合到一个接口中,但与后一个函数不同,getaddrinfo是可重入的,可支持IPv4、IPv6。

  • 3、函数参数:

    • node:一个主机名或地址串( IPv4的点分十进制数串或IPv6的十六进制数串)。如果hints.ai_flags包含AI_NUMERICHOST标志,则此参数必须是IP地址字符串;

    • service:一个服务名或十进制端口号数串。如果此参数被设置为一个服务名称,则会将其转换为相应的端口号。如果设置为NULL,则返回的套接字地址的端口号将保持未初始化状态。如果在hints.ai_flags中指定了AI_NUMERICSERV,并且此参数不为NULL,则此参数必须指向包含数字端口号的字符串;

    • hints:hints参数可以是一个空指针,也可以是一个指向某个addrinfo结构的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。hints参数中,调用者可以设置的字段有:ai_flags、ai_family、ai_socktype、ai_protocol。其中,ai_flags取值如下表:

      取值说明
      AI_PASSIVE套接字将用于被动打开.
      AI_CANONNAME告知getaddrinfo函数返回主机的规范名字.
      AI_NUMERICHOST防止任何类型的名字到地址映射,hostname参数必须是一个地址串。
      AI_NUMERICSERV防止任何类型的名字到服务映射, service参数必须是一个十进制端口号。AI__V4MAPPED
      AI_V4MAPPED如果同时指定ai_family成员的值为AF_INET6,那么如果没有可用的AAAA记录,就返回与A记录对应的IPv4映射的IPv6地址。
      AI_ALL如果同时指定AI_V4MAPPED标志,那么除了返回与AAAA记录对应的IPv6地址外,还返回与A记录对应的IPv4映射的IPv6地址。
      AI_ADDRCONFIG按照所在主机的配置选择返回地址类型,也就是只查找与所在主机回馈接口以外的网络接口配置的IP地址版本一致的地址。

      ai_family 取值一般为AF_XXX,例如:AF_INETAF_INET6AF_UNSPEC(不限制IP地址协议);
      ai_socktype 取值一般为SOCK_XXX,例如:SOCK_STREAMSOCK_DGRAM
      ai_protocol 字段指定返回的套接字地址的协议。在该字段中指定0表示getaddrinfo函数可以返回具有任何协议的套接字地址。

    • res:传出参数,如果本函数返回成功0,则 res 参数指向的变量已被填入一个指针,它指向的是由其中的 ai_next 成员串接起来的 addrinfo 结构链表。

  • 4、返回值:
    成功返回0,失败返回非0,取值如下表:

    常值说明
    EAI_AGAIN名字解析中临时失败
    EAI_BADFLAGSai_flags的值无效
    EAI_FAIL名字解析中不可恢复地失败
    EAI_FAMILY不支持ai_family
    EAI_MEMORY内存分配失败
    EAI_NONAMEhostname或service未提供,或者不可知
    EAI_OVERFTOW用户参数缓冲区溢出(仅限getnameinfo( )函数)
    EAI_SERVICE不支持ai_socktype类型的service
    EAI_SOCKTYPE不支持ai_socktype
    EAI_SYSTEM在errno变量中有系统错误返回

✨2.2 struct addrinfo 结构体说明

struct addrinfo结构体定义在头文件 netdb.h 中,结构体声明如下:

struct addrinfo {int              ai_flags;int              ai_family;int              ai_socktype;int              ai_protocol;socklen_t        ai_addrlen;struct sockaddr *ai_addr;char            *ai_canonname;struct addrinfo *ai_next;
};

在这里插入图片描述
结构体字段说明:

  • ai_flags:标志,在调用时使用,具体取值见上面 hints参数 的说明;
  • ai_family:IP协议族,一般取值有AF_INETAF_INET6AF_UNSPEC(不限制IP地址协议);
  • ai_socktype:socket类型,取值一般为SOCK_XXX,例如:SOCK_STREAMSOCK_DGRAM
  • ai_protocol:此字段指定返回的套接字地址的协议,一般有IPPROTO_UDPIPPROTO_TCP
  • ai_addrlen:返回的地址结构体ai_addr的长度。一般IPv4是4,IPv6是16;
  • ai_addr:存储IP地址数据,一般转换成struct sockaddr_instruct sockaddr_in6使用;
  • ai_canonname:正式的、标准的名称;
  • ai_next:用作链表结点指针,指向下一个struct addrinfo结点。

在这里插入图片描述

🎄三、gai_strerror、freeaddrinfo 函数

在使用 getaddrinfo 函数时,还有两个函数也会使用到,下面简单介绍一下这两个函数。

✨3.1 gai_strerror 函数介绍

  • 1、函数原型:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    const char *gai_strerror(int errcode);
    
  • 2、函数描述:
    getaddrinfo出错会返回的非0错误值,gai_strerror以这些值为它的唯一参数,返回一个指向对应的出错信息串的指针。
    常值说明
    EAI_AGAIN名字解析中临时失败
    EAI_BADFLAGSai_flags的值无效
    EAI_FAIL名字解析中不可恢复地失败
    EAI_FAMILY不支持ai_family
    EAI_MEMORY内存分配失败
    EAI_NONAMEhostname或service未提供,或者不可知
    EAI_OVERFTOW用户参数缓冲区溢出(仅限getnameinfo( )函数)
    EAI_SERVICE不支持ai_socktype类型的service
    EAI_SOCKTYPE不支持ai_socktype
    EAI_SYSTEM在errno变量中有系统错误返回

✨3.2 freeaddrinfo 函数介绍

  • 1、函数原型:

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    void freeaddrinfo(struct addrinfo *res);
    
  • 2、函数描述:
    由getaddrinfo返回的所有存储空间都是动态获取的(譬如来自malloc调用),包括addrinfo结构、ai_addr结构和ai_canonname字符串。这些存储空间需要通过调用freeaddrinfo返还给系统。

  • 3、参数
    res:res参数应指向由getaddrinfo返回的第一个addrinfo结构。这个链表中的所有结构以及由它们指向的任何动态存储空间(譬如套接字地址结构和规范主机名)都被释放掉。

  • 4、注意:
    如果getaddrinfo成功返回后,我们为了保存返回的信息而仅仅复制了返回的addrinfo结构,在调用freeaddrinfo后,就会存在一个错误:我们前面复制的addrinfo结构中的指针指向的内存空间已在调用freeaddrinfo后返还给系统。
    这种只复制结构体而没复制结构体字段指向的内容的方式称为浅复制;复制结构体又复制结构体字段指向的内容的方式称为深复制。上面例子中,如果确实要保存信息,可以使用深复制来保存。


在这里插入图片描述

🎄四、getaddrinfo 函数使用例子

// getaddrinfo_sample.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>int main(int argc, char *argv[]) {struct addrinfo hints, *result, *rp;// 定义addrinfo结构体变量int err;                         	// getaddrinfo函数返回值char ipstr[INET6_ADDRSTRLEN];       // 存储IP地址字符串的缓冲区if (argc != 2) {                    // 检查命令行参数数量是否正确fprintf(stderr, "Usage: %s hostname\n", argv[0]);return -1;}memset(&hints, 0, sizeof(hints));  	// 初始化hints结构体hints.ai_family = AF_UNSPEC;		// 不限制IP地址版本hints.ai_socktype = SOCK_STREAM;	// 使用TCP协议if ((err = getaddrinfo(argv[1], NULL, &hints, &result)) != 0) {  // 解析主机名并将结果存储在result指针中fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(err));return -1;}printf("IP addresses for %s:\n", argv[1]);for (rp = result; rp != NULL; rp = rp->ai_next) {	// 遍历result指针中的所有套接字地址结构void *addr;char *ipver;if (rp->ai_family == AF_INET) {	// IPv4地址struct sockaddr_in *ipv4 = (struct sockaddr_in *)rp->ai_addr;addr = &(ipv4->sin_addr);ipver = "IPv4";} else { 						// IPv6地址struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)rp->ai_addr;addr = &(ipv6->sin6_addr);ipver = "IPv6";}inet_ntop(rp->ai_family, addr, ipstr, sizeof(ipstr));  // 将套接字地址结构转换为IP地址字符串printf("  %s: %s\n", ipver, ipstr);                    // 打印IP地址和版本号}freeaddrinfo(result);   // 释放由getaddrinfo函数分配的内存return 0;    // 程序正常退出
}

运行结果:
下面是分别查询www.baidu.com(百度)、www.goolge.com(谷歌)、blog.csdn.net(CSDN)、localhost(本地主机名)、ip6-localhostip6-localnet的打印结果。
在这里插入图片描述

localhost(本地主机名)、ip6-localhostip6-localnet,这三个在/etc/hosts文件中有说明,可以发现与查询的一致。
在这里插入图片描述


在这里插入图片描述

🎄五、总结

👉本文重点介绍了 getaddrinfo、freeaddrinfo、gai_strerror 三个函数,并给出C语言使用例子。

通过本文的介绍,我们深入探讨了 Linux 系统中 getaddrinfo 函数的定义和使用场景。getaddrinfo 函数在网络编程中扮演着重要角色,允许开发人员根据主机名和服务名动态获取地址信息,为构建灵活且健壮的网络应用提供了便利。希望本文能帮助您更好地了解并应用 getaddrinfo 函数。

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

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

相关文章:

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

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

深度学习主流开源框架:Caffe、TensorFlow、Pytorch、Theano、Keras、MXNet、Chainer

2.6 深度学习主流开源框架 表2.1 深度学习主流框架参数对比 框架关键词总结 框架关键词基本数据结构&#xff08;都是高维数组&#xff09;Caffe“在工业中应用较为广泛”&#xff0c;“编译安装麻烦一点”BlobTensorFlow“安装简单pip”TensorPytorch“定位&#xff1a;快…...

[Linux] vim及gdb的使用

Linux工具使用 Vim编辑器使用Vim的基本概念vim的基本操作vim正常模式命令集vim底行模式命令集 gdb调试器使用背景使用 Vim编辑器使用 Vim的基本概念 vim我们所需要掌握的有三种模式&#xff0c;分别是命令模式、插入模式、底行模式。 正常/普通/命令模式 控制屏幕光标移动&a…...

Android WebView访问网页+自动播放视频+自动全屏+切换横屏

一、引言 近期&#xff0c;我发现电视家、火星直播等在线看电视直播的软件都已倒闭&#xff0c;而我奶奶也再无法通过这些平台看电视了。她已六十多岁&#xff0c;快七十岁啦。这些平台的倒下对我来说其实没有多大的影响&#xff0c;但是对于文化不多的她而言&#xff0c;生活中…...

php PhpSpreadsheet 读取日期变数字问题解决

问题描述&#xff1a; 使用PhpSpreadsheet 读取表格数据&#xff0c;日期格式读取后变成数字&#xff0c;如下图&#xff1a; 解决方案&#xff1a; $cell $sheet->getCell(H . $row)->getValue(); $toTimestamp \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimes…...

前端架构: 脚手架包管理工具之lerna的全流程开发教程

Lerna 1 &#xff09;文档 Lerna 文档 https://www.npmjs.com/package/lernahttps://lerna.js.org [请直达这个链接] 使用 Lerna 帮助我们做包管理&#xff0c;并不复杂&#xff0c;中间常用的命令并不是很多这里是命令直达&#xff1a;https://lerna.js.org/docs/api-referen…...

[安洵杯 2019]easy_serialize_php1

打开题目 题目源码&#xff1a; <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["user&q…...

【前端素材】推荐优质在线通用果蔬商城电商网页eStore平台模板(附源码)

一、需求分析 1、系统定义 通用果蔬网站是指专门提供各类果蔬产品展示和销售的在线平台。它将不同种类的新鲜水果、蔬菜、干果、坚果等聚集在一起&#xff0c;为消费者提供方便、快捷的购物渠道。 2、功能需求 通用果蔬网站是指专门提供各类果蔬产品展示和销售的在线平台。…...

开源软件的商业模式探析:开放与盈利的平衡

写在开头 开源软件的概念和应用已经成为了现代科技领域中的一个重要组成部分。然而&#xff0c;虽然开源软件的价值和影响力得到了广泛认可&#xff0c;但如何在开放的环境中找到商业盈利的平衡却是一个颇具挑战性的问题。本文将深入探讨开源软件的商业模式&#xff0c;从基本…...

使用全局事件总线实现任意组件间的通讯

本文以vue2中爷孙组件通讯为例&#xff0c;需求是点击孙组件的按钮&#xff0c;实现关闭爷组件的弹窗。 全局事件总线是通过Vue实例的事件系统来实现组件之间的通讯&#xff0c;可以方便地在任何组件中进行事件的触发和监听。 以下是使用全局事件总线实现爷孙组件通讯的步骤&a…...

文件基础和文件fd

文章目录 预备知识C语言的文件接口系统调用文件fd 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站。 预备知识 我们平时说文件就是说文件里…...

3dgs学习(二)—— 3d高斯与协方差矩阵及其几何意义

协方差矩阵与3d高斯 3d高斯与椭球与协方差矩阵 3d高斯&#xff0c;及3维空间内的正态分布。 通过一元正态分布的坐标系图像不难想象&#xff0c;3维空间中的正态分布点集中在一片椭球空间中&#xff0c;各方向长轴取决于各方向正态分布的方差。 而协方差矩阵通过计算多元之…...

ZStack Cube超融合入选IDC《中国超融合基础架构市场评估》报告

近日&#xff0c;IDC发布了《中国超融合基础架构市场评估&#xff0c;2023》。IDC针对中国超融合基础架构市场的发展现状展开了调研&#xff0c;明确了最终用户构建融合型云平台的痛点和难点&#xff0c;阐述了市场中各技术服务提供商的服务方案和优势&#xff0c;并对未来中国…...

每日一题——LeetCode1556.千位分隔符

方法一 个人方法&#xff1a; 把n转为字符串&#xff0c;逆序遍历n&#xff0c;把n的每个元素加入res&#xff0c;每三次加入.&#xff0c;最后将res翻转再转为字符串即为符合题目要求的结果 var thousandSeparator function(n) {nlet res[],lenn.length-1for(let ilen;i>…...

8.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-游戏底层功能对接类GameProc的实现

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;通过逆向分析确定游戏明文接收数据过程 码云地址&#xff08;master 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/titan 码云版本号&#xff1a;bcf7559184863febdcad819e48aa…...

Redis冲冲冲——事务支持,AOF和RDB持久化

目录 引出Redis事务支持&#xff0c;AOF和RDB持久化1、Redis的事务支持2、Redis的持久化 Redis冲冲冲——缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Redis冲冲冲——事务支持&#xff0c;AOF和RDB持久化 Redis事务支持&#xff0c;AOF和…...

路由菜单路径匹配方法

优化路由菜单路径匹配算法&#xff1a;实现获取整条线路的路径 引言 在前端开发中&#xff0c;路由菜单的路径匹配是一个常见的需求。我们经常需要根据给定的路径&#xff0c;找到对应的菜单项&#xff0c;并获取整条线路的路径。本文将介绍一个优化的路由菜单路径匹配算法&…...

设计模式浅析(九) ·模板方法模式

设计模式浅析(九) 模板方法模式 日常叨逼叨 java设计模式浅析&#xff0c;如果觉得对你有帮助&#xff0c;记得一键三连&#xff0c;谢谢各位观众老爷&#x1f601;&#x1f601; 模板方法模式 概念 模板方法模式&#xff08;Template Method Pattern&#xff09;在Java中是…...

无用工作、UBI与AI

有些隐晦和黑暗的事实无法陈述&#xff0c;因为任何的系统中“无用”的结局都是被无情的抛弃和淘汰&#xff0c;AI监督下的人类结局更是如此。 什么是无用工作&#xff1f; 无用无效工作通常指的是那些看似忙碌但实际上对社会或个人没有实质性贡献的工作。这类工作可能包括以下…...

【监控】grafana图表使用快速上手

目录 1.前言 2.连接 3.图表 4.job和path 5.总结 1.前言 上一篇文章中&#xff0c;我们使用spring actuatorPrometheusgrafana实现了对一个spring boot应用的可视化监控。 【监控】Spring BootPrometheusGrafana实现可视化监控-CSDN博客 其中对grafana只是打开了一下&am…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...