man 3 getaddrinfo

名称

  getaddrinfo, freeaddrinfo, gai_strerror - 网络地址和服务转换

提要

  

#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);

 描述

  已知node和service,可以确定一个网络主机和其中的一个服务,getaddrinfo()返回一个或多个addrinfo类型的结构体,每一个addrinfo结构体包含一个网络地址,该地址可以在调用bind(2)和connect(2)时使用。 getaddrinfo函数结合了gethostbyname(3)和getservbyname(3)的功能,同时getaddrinfo是可重入的,允许程序消除IPv4&IPv6的依赖。

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

  hints参数指向一个addrinfo类型的结构体,作为筛选返回的套结字地址结构的标准。如果hints为不为NULL,它指向的addrinfo结构体的ai_family, ai_socktype, ai_prototype指定返回的套结字地址集的筛选标准。

  ai_family  该域指定返回的套结字地址的地址族,有效值包括AF_INET和AF_INET6。如果指定为AF_UNSPEC,那么函数返回与node和service相关的任何地址族的套结字地址(包括IPv4和IPv6)。

  ai_socktype  该域指定返回的套结字地址集的协议。指定为0表示任何协议的套结字地址都会被返回。

  ai_flags  该域指定一些附加选项,多个选项可以通过或(||)操作结合起来。

  hints中的其他域必须要么为0要么为NULL。如果指定hints为NULL,等价与ai_socktype=ai_prototype=0&ai_family=AF_UNSPEC&ai_flags=AI_V4MAPP||AI_ADDRCONFIG.

  node要么为数值型的网络地址(对于IPv4为点分十进制表示法,对于IPv6为十六进制字符串格式),要么是一个网络主机域名,当然其对应的网络地址将会被寻找并且解析。如果hints.ai_flags包含AI_NUMERICHOST,那么node必须指定为数值型的网络地址。AI_NUMERIC抑制任何潜在的冗余网络主机地址寻找。

  如果hints.ai_flags中指定AI_PASSIVE,并且node为NULL,那么返回的套结字地址将会适用与bind()函数,返回的地址将会包含“通用地址“(对于IPv4为INADDR_ANY,对于IPv6为IN6ADDR_ANY_INIT),“通用地址”一般用于服务器端程序,用于接受来自任何网络主机的连接。如果node不为NULL,那么AI_PASSIVE将会被忽略。

  如果hints.ai_flags中没有指定AI_PASSIVE, 那么返回的套结字地址将会适用于connect,sendto,和sendmsg函数。如果node为NULL,那么返回的网络地址将会被设置为回环接口地址(loopback interface address)(对于IPv4为INADDR_LOOPBACK,对于IPv6为IN6ADDR_LOOPBACK_INIT),该地址通常被用于和在相同主机上运行的同级程序进行通信的应用。

  service设置返回的地址结构中的port,如果该参数为一个服务名称,将会被转换为相应的端口号。该参数也可以被指定为十进制数,并且会被简单的转换为二进制。如果service为NULL,那么返回的套结字地址中的port将不会被初始化。如果hints.ai_flags中指定了AI_NUMERICSERV并且service不为NULL,那么service必须指向一个代表十进制端口号的字符串。在不必要的情况下,AI_NUMERICSERV用于抑制名字解析服务的调用。

  node和service不可同时为NULL。

  getaddrinfo函数分配并且初始化一个addrinfo结构体类型的链表,每个节点代表一个返回的套结字地址,返回指向链表头部节点的指针,节点由next域连接起来。

  有很多原因导致结果链表中会有多个addrinfo结构体:网络主机是分散的,或者可以通过多种协议访问(AF_INET或者AF_INET6),或者相同的服务(service)对于多种套结字类型都是有效的(SOCK_STREAM或者SOCK_DGRAM)。正常情况下,应用程序应该使用函数返回的套结字地址顺序使用地址,getaddrinfo()函数所使用的排序函数定义在RFC 3484;对于某些特定的系统,这个顺序可以通过修改/etc/gai.conf(>=glibc 2.5)被改变。

  如果hints.ai_flags包含AI_CANONNAME,那么返回的链表中的第一个addrinfo结构体的ai_canonname域被设置为指向主机的官方名称。

  返回的链表中的addrinfo结构体中的其他域按如下初始化:

  *ai_family, ai_socktype, ai_prototype域返回创建套结字(socket)的参数(这些域与socket()函数相应的参数具有相同的含义)。例如ai_family可以是AF_INET或者AF_INET6; ai_socktype可以使SOCK_STREAM或者SOCK_DGRAM; ai_prototype可以是套结字的相关协议。

  *指向套结字地址的指针被赋给ai_addr域;套结字地址的长度,以字节为单位,被赋给ai_addrlen.

如果hints.ai_flags指定了AI_V4MAPPED,并且ai_family被指定为AF_INET,并且没有找到IPv6地址,那么IPv4映射的IPv6地址将会被返回。如果hints.ai_flags同时指定了AI_V4MAPPED和AI_ALL, 那么IPv6和IPv4映射的IPv6地址将会被返回。如果AI_V4MAPPED没有被指定,那么AI_ALL将会被忽略。

  freeaddrinfo()函数释放动态分配给res这个临界链表的地址空间。

  返回值:

  getaddrinfo成功执行返回0,或者返回相应的非0错误码:

  EAI_ADDRFAMILY, EAI_AGAIN, EAI_BADFLAGS, EAI_FAIL, EAI_FAMILY, EAI_MEMORY,EAI_NODATA, EAI_NONAME, EAI_SERVICE,EAI_SOCKTYPE, EAI_SYSTEM.

转载于:https://www.cnblogs.com/cq-shihao/p/5280472.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值