getaddrinfo 子例程
用途
与协议无关的主机名到地址转换。
库
库 (libc.a)
语法
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo (hostname, servname, hints, res)
const char *hostname;
const char *servname;
const struct addrinfo *hints;
struct addrinfo **res;描述
hostname 和 servname 参数描述要引用的主机名和/或服务名称。 零个或其中一个自变量可能为 NULL。 非 NULL 主机名可以是主机名或数字主机地址字符串 (对于 IPv4 为点分十进制,对于 IPv6为十六进制)。 非 NULL 服务名称可以是服务名称或十进制端口号。
hints 参数指定有关所需返回信息的提示。 hostname 和 servname 参数是指向以 null 结束的字符串或 NULL 的指针。 其中一个或两个自变量必须是非 NULL 指针。 在正常客户机方案中,同时指定了 hostname 和 servname 参数。 在正常服务器方案中,仅指定 servname 参数。 非 NULL 主机名字符串可以是主机名或数字主机地址字符串 (例如,点分十进制 IPv4 地址或 IPv6 十六进制地址)。 非 NULL servname 字符串可以是服务名称或十进制端口号。
调用者可以选择性地传递由 hints 参数指向的 addrinfo 结构,以提供有关调用者支持的套接字类型的提示。 在此 提示 结构中,除 ai_flags, ai_eflags ai_family, ai_socktype以外的所有成员。 并且 ai_protocol 必须为零或 NULL 指针。 对于 ai_family , PF_UNSPEC 值表示调用者将接受任何协议系列。 ai_socktype 的值为零表示调用者接受任何套接字类型。 ai_protocol 的值为零表示调用者接受任何协议。 例如,如果调用者仅处理 TCP 而不是 UDP ,那么在调用 getaddrinfo 子例程时,应该将 hints 结构的 ai_socktype 成员设置为 SOCK_STREAM。 如果调用者仅处理 IPv4 而不处理 IPv6,那么在调用 getaddrinfo 时,应该将 hints 结构的 ai_family 成员设置为 PF_INET。 如果 getaddrinfo 中的 hints 参数是 NULL 指针,那么与调用者在将 ai_family 设置为 PF_UNSPEC 的情况下填充初始化为零的 addrinfo 结构相同。
成功返回时,将通过 res 参数返回指向一个或多个 addrinfo 结构的链接列表的指针。 调用者可以通过遵循 ai_next 指针来处理此列表中的每个 addrinfo 结构,直到迂到 NULL 指针为止。 在每个返回的 addrinfo 结构中,三个成员 ai_family, ai_socktype, 而 ai_protocol 是调用 socket 子例程的相应自变量。 在每个 addrinfo 结构中, ai_addr 成员指向其长度由 ai_addrlen 成员指定的文件插入套接字地址结构。
如果在 hints 结构的 ai_flags 成员中设置了 AI_PASSIVE 位,那么调用者计划在对 bind 子例程的调用中使用返回的套接字地址结构。 如果 hostname 参数是 NULL 指针,那么对于 IPv4 地址,套接字地址结构的 IP 地址部分将设置为 INADDR_ANY ,对于 IPv6 地址,将设置为 IN6ADDR_ANY_INIT 。
如果未在提示结构的 ai_flags 成员中设置 AI_PASSIVE 位,那么返回的套接字地址结构已准备好调用 connect 子例程 (用于面向连接的协议) 或 connect。 sendto或 sendmsg 子例程 (对于无连接协议)。 如果 hostname 参数是 NULL 指针,那么套接字地址结构的 IP 地址部分将设置为回送地址。
如果在提示结构的 ai_flags 成员中设置了 AI_CANONNAME 位,那么成功返回后,链接列表中第一个 addrinfo 结构的 ai_canonname 成员将指向包含指定主机名的规范名称的以 NULL 结束的字符串。
如果指定了 AI_NUMERICHOST 标志,那么提供的非 NULL 节点名字符串是数字主机地址字符串。 否则,将返回 (EAI_NONAME) 错误。 此标志阻止调用任何类型的名称解析服务 (例如 DNS)。
如果指定了 AI_NUMERICSERV 标志,那么提供的非 NULL servname 字符串是数字端口字符串。 否则,将返回 (EAI_NONAME) 错误。 此标志可防止调用任何类型的名称解析服务。
如果 AI_V4MAPPED 标志与 AF_INET6的 ai_family 值一起指定, 当找不到匹配的 IPv6 地址 (ai_addrlen 为 16) 时, getaddrinfo 子例程返回 IPv4-mapped IPv6 地址。 例如,使用 DNS 时,如果找不到 AAAA 或 A6 记录,那么将对 A 记录进行查询。 任何找到的地址都将作为 IPv4-mapped IPv6 地址返回。 除非 ai_family 等于 AF_INET6,否则将忽略 AI_V4MAPPED 标志。
如果在提示结构的 ai_flags 成员中指定了 AI_EXTFLAGS ,并且将 ai_eflags 指定为非零值,那么地址选择算法将受影响。 地址选择算法使用一组有序规则 (RFC 3484) 对返回的 addrinfo 结构列表进行排序,同时考虑每个 addrinfo 结构的 ai_addr 成员中包含的地址以及可从中访问此地址的源地址。 ai_eflags 表示首选项,意味着如果更高的规则之前没有对地址集进行排序,那么将应用下面描述的规则。
可以将 ai_eflags 设置为以下标志的组合:
- IPV6_PREFER_SRC_HOME: 首选可从家庭源地址访问的地址
- IPV6_PREFER_SRC_COA: 首选可从 Care-of 源地址访问的地址
- IPV6_PREFER_SRC_TMP: 首选可从临时地址访问的地址
- IPV6_PREFER_SRC_PUBLIC: 可从公共源地址访问的首选地址
- IPV6_PREFER_SRC_CGA: 可从加密生成的地址 (CGA) 源地址访问的首选地址
- IPV6_PREFER_SRC_NONCGA: 可从非 CGA 源地址访问的首选地址
例如, IPV6_PREFER_SRC_TMP ai_eflags 表示地址选择算法将对返回的具有可从临时地址访问的地址的 addrinfo 结构进行排序,在可能的情况下,对具有可从公共地址访问的地址的结构进行排序。 同时设置矛盾标志 (例如 IPV6_PREFER_SRC_TMP 和 IPV6_PREFER_SRC_PUBLIC) 会导致错误 EINVAL。
如果指定了 AI_ADDRCONFIG 标志,那么仅当节点至少配置了一个 IPv6 源地址时,才应查询 AAAA 或 A6 记录。 仅当节点至少配置了一个 IPv4 源地址时,才应该对 A 记录进行查询。 回送地址被视为无效,无法作为已配置的源地址。
getaddrinfo 子例程返回的所有信息都是动态分配的: addrinfo 结构,套接字地址结构和 addrinfo 结构指向的规范主机名字符串。 要将此信息返回到系统,将调用 freeaddrinfo 子例程。
addrinfo 结构定义为:
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IP=PROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canoncial name for hostname */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
int ai_eflags; /* Extended flags for special usage */
}返回值
如果查询成功,那么将通过 res 参数返回指向一个或多个 addrinfo 结构的链接列表的指针。 零返回值表示成功。 如果查询失败,那么将返回非零错误代码。
错误代码
以下名称是非零错误代码。 请参阅 netdb.h 以获取进一步定义。
| 项 | 描述 |
|---|---|
| EAI_ADDRFAMILY | 主机名的地址系列不受支持 |
| 又是EAI_起 | 名称解析中发生临时故障 |
| EAI_BADFLAGS | ai_flags 的值无效 |
| EAI_FAIL | 名称解析中发生不可恢复故障 |
| EAI_FAMILY | ai_family 不受支持 |
| EAI_MEMORY | 内存分配失败 |
| EAI_NODATA | 没有与 hostname 关联的地址 |
| EAI_NONAME | 未提供 hostname 或 servname ,或未知 |
| EAI_SERVICE | ai_socktype 不支持 servname |
| EAI_SOCKTYPE | ai_socktype 不受支持 |
| EAI_SYSTEM | errno 中返回了系统错误 |
| eai_badextflags | ai_eflags 的值无效。 |