【问题标题】:Why must the struct addrinfo be partially filled out before using getaddrinfo() on it?为什么在使用 getaddrinfo() 之前必须部分填写 struct addrinfo?
【发布时间】:2016-09-17 22:05:18
【问题描述】:
我一直在关注 Beej 的网络编程指南,但无法理解为什么我们必须在调用 getaddrinfo() 之前填写 struct addrinfo 的某些字段?另外,为什么它返回一个指向 multiple addrinfo 结构列表的指针?既然只有一台主机,为什么会有多个地址呢?
【问题讨论】:
-
关于返回部分:它是一个可以在任何条件下工作的函数,因此它应该是通用的。一个主机可能有多个 NIC。但即使它只有一个,也可能有多个条目。试试ipconfig -all(在Win下),或ifconfig -a(在Linux下);每个输出记录都对应于addrinfo struct 之一(因此您几乎总是拥有超过 1 个)。关于第一艺术,您可以阅读getaddrinfo 手册:Ux 或Win。
-
标签:
sockets
network-programming
getaddrinfo
【解决方案1】:
为什么我们必须在之前填写struct addrinfo的一些字段
调用 getaddrinfo()?
我假设您询问的是 hints 参数。此参数可用于指定您希望从getaddrinfo() 获得的响应类型。例如,无论您是想要仅 IPv4 的 DNS 查找 (AF_INET) 还是 IPv6 的 (AF_INET6),来自 man page:
hints 参数指向一个 addrinfo 结构,该结构指定
选择返回的套接字地址结构的标准
res 指向的列表。如果提示不是 NULL 它指向一个
addrinfo 结构,其 ai_family、ai_socktype 和 ai_protocol
指定限制由返回的套接字地址集的条件
getaddrinfo(),如下:
ai_family This field specifies the desired address family for the
returned addresses. Valid values for this field include
AF_INET and AF_INET6. The value AF_UNSPEC indicates that
getaddrinfo() should return socket addresses for any
address family (either IPv4 or IPv6, for example) that
can be used with node and service.
ai_socktype This field specifies the preferred socket type, for
example SOCK_STREAM or SOCK_DGRAM. Specifying 0 in this
field indicates that socket addresses of any type can be
returned by getaddrinfo().
ai_protocol This field specifies the protocol for the returned socket
addresses. Specifying 0 in this field indicates that
socket addresses with any protocol can be returned by
getaddrinfo().
ai_flags This field specifies additional options, described below.
Multiple flags are specified by bitwise OR-ing them
together.
All the other fields in the structure pointed to by hints must
contain either 0 or a null pointer, as appropriate.
为什么它返回一个指向多个 addrinfo 结构列表的指针?
既然只有一台主机,为什么会有多个地址呢?
域名通常解析为多个 IP 地址。
例如,对我来说,stackoverflow.com 目前解析为以下地址:
$ nslookup stackoverflow.com
Non-authoritative answer:
Server: UnKnown
Address: 10.0.0.138
Name: stackoverflow.com
Addresses: 151.101.65.69
151.101.129.69
151.101.1.69
151.101.193.69
所有这些地址都是 stackoverflow.com