当前位置: 首页 > 编程日记 > 正文

getaddrinfo()函数详解

1. 概述IPv4中使用gethostbyname()函数完成主机名到地址解析,这个函数仅仅支持IPv4,且不允许调用者指定所需地址类型的任何信息,返回的结构只包含了用于存储IPv4地址的空间。IPv6中引入了getaddrinfo()的新API,它是协议无关的,既可用于IPv4也可用于IPv6。getaddrinfo函数能够处理名字到地址以及服务到端口这两种转换,返回的是一个addrinfo的结构(列表)指针而不是一个地址清单。这些addrinfo结构随后可由套接口函数直接使用。如此以来,getaddrinfo函数把协议相关性安全隐藏在这个库函数内部。应用程序只要处理由getaddrinfo函数填写的套接口地址结构。该函数在 POSIX规范中定义了。2. 函数说明包含头文件
#include<netdb.h>函数原型
int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );参数说明
hostname:一个主机名或者地址串(IPv4的点分十进制串或者IPv6的16进制串)
service:服务名可以是十进制的端口号,也可以是已定义的服务名称,如ftp、http等
hints:可以是一个空指针,也可以是一个指向某个addrinfo结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。举例来说:如果指定的服务既支持TCP也支持UDP,那么调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM使得返回的仅仅是适用于数据报套接口的信息。
result:本函数通过result指针参数返回一个指向addrinfo结构体链表的指针。
返回值:0——成功,非0——出错3. 参数设置在getaddrinfo函数之前通常需要对以下6个参数进行以下设置:nodename、servname、hints的ai_flags、ai_family、ai_socktype、ai_protocol。
在6项参数中,对函数影响最大的是nodename,sername和hints.ai_flag,而ai_family只是有地址为v4地址或v6地址的区别。ai_protocol一般是为0不作改动。getaddrinfo在实际使用中的几种常用参数设置
一般情况下,client/server编程中,server端调用bind(如果面向连接的还需要listen),client则不用掉bind函数,解析地址后直接connect(面向连接)或直接发送数据(无连接)。因此,比较常见的情况有
(1)    通常服务器端在调用getaddrinfo之前,ai_flags设置AI_PASSIVE,用于bind;主机名nodename通常会设置为NULL,返回通配地址[::]。
(2)    客户端调用getaddrinfo时,ai_flags一般不设置AI_PASSIVE,但是主机名nodename和服务名servname(更愿意称之为端口)则应该不为空。
(3)    当然,即使不设置AI_PASSIVE,取出的地址也并非不可以被bind,很多程序中ai_flags直接设置为0,即3个标志位都不设置,这种情况下只要hostname和servname设置的没有问题就可以正确bind。上述情况只是简单的client/server中的使用,但实际在使用getaddrinfo和参考国外开源代码的时候,曾遇到一些将servname(即端口)设为NULL的情况(当然,此时nodename必不为NULL,否则调用getaddrinfo会报错)。
以下分情况进行了测试:
(1)    如果nodename是字符串型的IPv6地址,bind的时候会分配临时端口;
(2)    如果nodename是本机名,servname为NULL,则根据操作系统的不同略有不同,本文仅在WinXP和Win2003上作了测试。a)    WinXP系统(SP2)返回loopback地址[::1]b)    Win2003则将本机的所有IPv6地址列表加以返回。因为通常一台IPv6主机都有可能不止一个IPv6地址,比如fe80::1(本机 loopback地址)、fe80::***的Link-Local地址、3ffe:***的全局地址等等。这种情况下调用getaddrinfo会将这些地址全部返回,调用者应该注意如何使用这些地址。另外要注意的是,对于fe80::的地址在绑定的时候必须标明接口地址,即使用 fe80::20d:60ff:fe78:51c2%4或fe80::1%1这样的地址格式,通过getaddrinfo直接取出fe80地址好像无法直接bind。4. 使用细节如果本函数返回成功,那么由result参数指向的变量已被填入一个指针,它指向的是由其中的ai_next成员串联起来的addrinfo结构链表。可以导致返回多个addrinfo结构的情形有以下2个:1.    如果与hostname参数关联的地址有多个,那么适用于所请求地址簇的每个地址都返回一个对应的结构。2.    如果service参数指定的服务支持多个套接口类型,那么每个套接口类型都可能返回一个对应的结构,具体取决于hints结构的ai_socktype成员。我们必须先分配一个hints结构,把它清零后填写需要的字段,再调用getaddrinfo,然后遍历一个链表逐个尝试每个返回地址。getaddrinfo解决了把主机名和服务名转换成套接口地址结构的问题。其中,如果getaddrinfo出错,那么返回一个非0的错误值。
#include<netdb.h>
const char *gai_strerror( int error );
该函数以getaddrinfo返回的非0错误值的名字和含义为他的唯一参数,返回一个指向对应的出错信息串的指针。由getaddrinfo返回的所有存储空间都是动态获取的,这些存储空间必须通过调用freeaddrinfo返回给系统。
#include< netdb.h >
void freeaddrinfo( struct addrinfo *ai );
ai参数应指向由getaddrinfo返回的第一个addrinfo结构。这个连表中的所有结构以及它们指向的任何动态存储空间都被释放掉

addrinfo结构
结构 固定的参数
typedef struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char* ai_canonname;
struct sockaddr* ai_addr;
struct addrinfo* ai_next;
} ai_addrlen must be zero or a null pointer
ai_canonname must be zero or a null pointer
ai_addr must be zero or a null pointer
ai_next must be zero or a null pointer
可以改动的参数
ai_flags:AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST
ai_family: AF_INET,AF_INET6
ai_socktype:SOCK_STREAM,SOCK_DGRAM
ai_protocol:IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.3 参数说明
在getaddrinfo函数之前通常需要对以下6个参数进行以下设置:nodename、servname、hints的ai_flags、ai_family、ai_socktype、ai_protocol
在6项参数中,对函数影响最大的是nodename,sername和hints.ai_flag
而ai_family只是有地址为v4地址或v6地址的区别。而ai_protocol一般是为0不作改动。
其中ai_flags、ai_family、ai_socktype说明如下:
参数 取值 值 说明
ai_family AF_INET 2 IPv4
AF_INET6 23 IPv6
AF_UNSPEC 0 协议无关
ai_protocol IPPROTO_IP 0 IP协议
IPPROTO_IPV4 4 IPv4
IPPROTO_IPV6 41 IPv6
IPPROTO_UDP 17 UDP
IPPROTO_TCP 6 TCP
ai_socktype SOCK_STREAM 1 流
SOCK_DGRAM 2 数据报
ai_flags AI_PASSIVE 1 被动的,用于bind,通常用于server socket
AI_CANONNAME 2AI_NUMERICHOST 4 地址为数字串对于ai_flags值的说明:
AI_NUMERICHOST AI_CANONNAME AI_PASSIVE
0/1 0/1 0/1如上表所示,ai_flagsde值范围为0~7,取决于程序如何设置3个标志位,比如设置ai_flags为“AI_PASSIVE|AI_CANONNAME”,ai_flags值就为3。三个参数的含义分别为:
(1)AI_PASSIVE当此标志置位时,表示调用者将在bind()函数调用中使用返回的地址结构。当此标志不置位时,表示将在connect()函数调用中使用。
当节点名位NULL,且此标志置位,则返回的地址将是通配地址。
如果节点名NULL,且此标志不置位,则返回的地址将是回环地址。
(2)AI_CANNONAME当此标志置位时,在函数所返回的第一个addrinfo结构中的ai_cannoname成员中,应该包含一个以空字符结尾的字符串,字符串的内容是节点名的正规名。
(3)AI_NUMERICHOST当此标志置位时,此标志表示调用中的节点名必须是一个数字地址字符串。

 
代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s hostname\n",
argv[1]);
exit(1);   
}struct addrinfo *answer, hint, *curr;
char ipstr[16];   
bzero(&hint, sizeof(hint));
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_STREAM;int ret = getaddrinfo(argv[1], NULL, &hint, &answer);
if (ret != 0) {
fprintf(stderr,"getaddrinfo: &s\n",
gai_strerror(ret));
exit(1);
}for (curr = answer; curr != NULL; curr = curr->ai_next) {
inet_ntop(AF_INET,
&(((struct sockaddr_in *)(curr->ai_addr))->sin_addr),
ipstr, 16);
printf("%s\n", ipstr);
}freeaddrinfo(answer);
exit(0);
}

转载于:https://www.cnblogs.com/zhangsf/p/3145552.html

相关文章:

OpenStack环境搭建(三:Computer与Controller节点的安装及配置)

实验要求&#xff1a; 完成Virtual box平台安装&#xff0c;会应用相关操作&#xff1b;在virtual box虚拟平台上部署Fuel Master节点&#xff1b;在virtual box虚拟平台上部署计算节点Computer&#xff1b;在virtual box虚拟平台上部署控制节点Controller&#xff1b;在web控…

iOS - 支持水平 / 垂直显示自动滚动的跑马灯控件 --- SKAutoScrollLabel 的使用和实现

原文链接&#xff1a;http://www.jianshu.com/p/7221bc08f26aSKAutoScrollLabel 是一个同时支持水平 / 垂直两种类型的 “跑马灯” 效果的自动滚动 UILabel。在滚动的边缘使用了梯度褪色来解决滚动边缘生硬的效果问题&#xff0c;总体效果呈现出混然天成的感觉&#xff0c;并且…

Git简明手册

文&#xff0f;AbnerKang&#xff08;简书作者&#xff09;原 文链接&#xff1a;http://www.jianshu.com/p/d7a7ba4f2341?utm_campaignmaleskine& utm_contentnote&utm_mediumreader_share&utm_sourceweixin&fromtimeline&isappinstalled0著作权归作者所…

今天是2013年06月21日,博客之路开始了!

RT&#xff0c;从今天开始&#xff0c;准备养成写博客的习惯。 一是对学习的成果进行总结  二是检验自己是否真的弄懂某一个问题  三是分享出来与大家共勉。从此开启我的程序人生之路吧&#xff01;转载于:https://www.cnblogs.com/penghongwei/p/3147999.html

OpenStack环境搭建(四:web控制端各节点的部署及配置)

实验要求&#xff1a; 完成Virtual box平台安装&#xff0c;会应用相关操作&#xff1b;在virtual box虚拟平台上部署Fuel Master节点&#xff1b;在virtual box虚拟平台上部署计算节点Computer&#xff1b;在virtual box虚拟平台上部署控制节点Controller&#xff1b;在web控…

Spring+SpringMVC+shiro+mysql(一)

SpringSpringMVCshiromysql&#xff08;一&#xff09; 最近要做个后台管理系统&#xff0c;就会设计到权限的管理控制&#xff0c;于是就想到 shiro &#xff0c;下面是自己对Springshiro的一点点理解&#xff0c;记录下来&#xff0c;一起多探讨&#xff1a; 项目结构 1. pom…

【iOS】Socket/TCP 通信 发送 NSString 字符串格式数据

Socket/TCP 原理这里就不阐述了&#xff0c;网上一搜一大堆&#xff0c;直接上关键代码。 【注】iOS 目前有非常著名的第三方库 CocoaAsyncSocket 可以使用&#xff0c;但是我们项目当时做大数据上报要求直接发送 NSString 格式数据&#xff0c;所以自己写了一个简易版 TCP 连接…

[Win]进程间通信——邮槽Mailslot

进程间通信 进程的地址空间是私有的。出于安全性的目的&#xff0c;如果一个进程不具有特殊的权限&#xff0c;是无法访问另外一个进程的内存空间的&#xff0c;也无法知道内存中保存的数据的意义。但是在一些具体的应用情况下需要多个进行相互配合&#xff0c;有时计算机用户也…

OpenStack环境搭建(五:附加项虚拟机文件备份使用)

实验要求&#xff1a; 完成Virtual box平台安装&#xff0c;会应用相关操作&#xff1b;在virtual box虚拟平台上部署Fuel Master节点&#xff1b;在virtual box虚拟平台上部署计算节点Computer&#xff1b;在virtual box虚拟平台上部署控制节点Controller&#xff1b;在web控…

IOS入门-TargetAction

创建一个UIButton 并用Target - Action来监听它的点击事件 Target -- self控制器 Action -- 具体动作&#xff0c;self控制器中的某个方法 forControlEvents:UIControlEventTouchUpInside -- 表示监听的事件 1 - (void)btnclick:(id)sender2 {3 NSLog("点击%" ,…

【iOS_Development】文件操作

原文链接&#xff1a;http://www.jianshu.com/p/c5820ab6836biOS 文件操作 —— 由anticipate_91分享NSFileManager&#xff1a;是用来管理文件系统的&#xff0c;它可以用来进行常见的文件\文件夹操作获取NSFileManager示例[NSFileManager defaultManager] 增删改查 1. 创建文…

仿人智能控制器的参数简化(已发表于《计算机测量与控制》2013年第4期)

转载于:https://www.cnblogs.com/snake-hand/p/3153313.html

OpenStack环境搭建(六:常见问题及解决方案总结)

实验要求&#xff1a; 完成Virtual box平台安装&#xff0c;会应用相关操作&#xff1b;在virtual box虚拟平台上部署Fuel Master节点&#xff1b;在virtual box虚拟平台上部署计算节点Computer&#xff1b;在virtual box虚拟平台上部署控制节点Controller&#xff1b;在web控…

工作区和暂存区

Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。 先来看名词解释。 工作区&#xff08;Working Directory&#xff09; 就是你在电脑里能看到的目录&#xff0c;比如我的learngit文件夹就是一个工作区&#xff1a; 版本库&#xff08;Repository&#xff09; 工…

Lucene类介绍

IndexWriter:lucene中最重要的的类之一&#xff0c;它主要是用来将文档加入索引&#xff0c;同时控制索引过程中的一些参数使用。 Analyzer luceneAnalyzer new StandardAnalyzer(); IndexWriter indexWriter new IndexWriter(indexDir, luceneAnalyzer, true );…

iOS 开发之沙盒机制 文件操作 (NSFielManager)

原文链接&#xff1a;http://www.jianshu.com/p/349855b5a8aeiOS APP 可以在自己的沙盒里读写文件&#xff0c;但是&#xff0c;不可以访问其他 APP 的沙盒。每一个 APP 都是一个信息孤岛&#xff0c;相互是不可以进行通信的&#xff0c;唯独可以通过 URL Scheme。沙盒里面的文…

手动部署OpenStack环境(一:Virtual Box 5.1 环境的安装及配置)

任务一、Virtual Box 5.1 环境的安装及配置 1.1、安装环境检查 1.2、创建安装目录 1.3、安装及配置 实验目的及要求 完成Virtual box平台安装&#xff0c;会应用相关操作&#xff1b;在virtual box虚拟平台上部署网络节点Network&#xff1b;在virtual box虚拟平台上部署计算…

iOS动画系列之九:实现点赞的动画及播放起伏指示器

iOS动画系列&#xff0c;共十篇。现在写到第九篇啦。感兴趣的可以通过下面的传输门进到其他几篇文章里面。 第一篇&#xff1a;iOS动画系列之一&#xff1a;通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画(上) 第二篇&#xff1a;iOS动画系列之二&#xff1a;…

MySql5.7环境搭建

1. 安装mysql的linux系统 [rootgrewan ~]# cat /etc/redhat-release CentOS release 6.7 (Final) [rootgrewan ~]# uname -a Linux grewan 2.6.32-573.26.1.el6.x86_64 #1 SMP Wed May 4 00:57:44 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux [rootgrewan ~]# 注意&#xff1a;l…

Toad 修改起始窗口

Toad默认窗口时Editor&#xff0c; 如果想要修改为Schema Browser可以通过以下步骤进行修改&#xff08;以Toad9.6为例&#xff09;&#xff1a; 1&#xff0c;点击菜单栏上的View下拉菜单 2&#xff0c;选择Toad Options...菜单 3&#xff0c;在打开窗口的左边功能列表中找到并…

手动部署OpenStack环境(二:CentOS6.6虚拟机的安装及配置)

任务二、CentOS 6.6虚拟机的安装及配置 2.1、安装环境检查 2.2、安装及配置controller0节点 2.3、安装及配置computer0节点 2.4、安装及配置network0节点 2.5、对各节点进行基础配置及服务安装 任务二&#xff1a;CentOS6.6虚拟机的安装及配置 2.1、安装环境检查 2.1.1在…

练习-----查询

第一步&#xff1a;建表 1 create table student #学生表2 (3 Sno varchar(20) primary key, #学号&#xff0c;主键4 Sname varchar(20) not null, #学生姓名5 Ssex varchar(20) not null, #学生性别6 Sbirthday datetime, #学生出生日期7 Class …

UIActivityViewController使用

苹果从iOS6开始&#xff0c;提供了一个活动列表视图&#xff0c;为分享和操作数据提供了一个统一的服务接口&#xff0c;通过UIActivityViewController来控制它的呈现和关闭&#xff0c;凡是继承UIActivity抽象类的子类对象都可以放在列表中呈现出来。如下图所示&#xff1a; 活…

SQL Server系统表sysobjects介绍与使用

关于SQL Server数据库的一切信息都保存在它的系统表格里。我怀疑你是否花过比较多的时间来检查系统表格&#xff0c;因为你总是忙于用户表格。但是&#xff0c;你可能需要偶尔做一点不同寻常的事&#xff0c;例如数据库所有的触发器。你可以一个一个地检查表格&#xff0c;但是…

手动部署OpenStack环境(三:OpenStack环境预配置)

任务三、OpenStack环境预配置 3.1、本地OpenStack yum源制作 任务三&#xff1a;OpenStack环境预配置 3.1、本地OpenStack yum 源制作 3.1.1、拷贝镜像文件源到本地 3.1.2、查看createrepo是否安装&#xff0c;并使用yum方法安装。 &#xff08;此操作只在controller0主机进…

Java 集合框架(二)—— ArrayList

二、数组列表 —— ArrayList 1、构造方法 ArrayList 是 Java 中的动态数组&#xff0c;底层实现就是对象数组&#xff0c;只不过数组的容量会根据情况来改变。 它有个带 int 类型参数的构造方法&#xff0c;根据传入的参数&#xff0c;扩展初始化的数组容量&#xff0c;这个方…

Linux X Window System运行原理和启动过程

本文主要说明X Window System的基本运行原理&#xff0c;其启动过程&#xff0c;及常见的跨网络运行X Window System。 一) 基本运行原理 X Window System采用C/S结构&#xff0c;但和我们常见的C/S不同。常见的C/S结构中&#xff0c;称提供服务的一方为server&#xff0c;即服…

悬浮球 / 悬浮按钮 / 辅助按钮

原文链接&#xff1a;https://github.com/jinht/FloatingBall类似于 iOS 系统自带的 AssistiveTouch / 京东 / 聚划算 / 建行等的辅助按钮 —— 由anticipate_91分享FloatingBall Function Description 这是一个类似于iOS系统自带的AssistiveTouch/京东《我的》部分的悬浮按钮等…

手动部署OpenStack环境(四:安装控制器必备软件)

任务四、安装控制器必备组件 4.1、安装MySQL服务&#xff08;controller0&#xff09; 4.2、安装Rabbitmq消息队列&#xff08;controller0&#xff09; 4.3、Keystone认证&#xff08;controller0&#xff09; 4.4、glance的安装与配置&#xff08;controller0&#xff09; 4.…

cocoaPods安装、更新第三方库

pod install 换成 pod install --verbose --no-repo-update pod update 换成 pod update --verbose --no-repo-update这是因为&#xff1a;目前&#xff0c;cocoaPods正在被墙中......转载于:https://www.cnblogs.com/hello-Huashan/p/5542456.html