C++ getaddrinfo:如果指定了节点名,AI_被动忽略的方式是什么?

C++ getaddrinfo:如果指定了节点名,AI_被动忽略的方式是什么?,c++,c,sockets,networking,posix,C++,C,Sockets,Networking,Posix,引用以下规范: 如果指定了AI_PASSIVE标志,则返回的地址信息应适用于绑定套接字以接受指定服务的传入连接。在这种情况下,如果nodename参数为空,则套接字地址结构的IP地址部分对于IPv4地址应设置为INADDR\u ANY,对于IPv6地址应设置为INADDR\u ANY\u INIT 这是有道理的。如果指定AI\u PASSIVE,则可以在返回的地址上bind()/listen()/accept()。如果nodename为空,则返回的地址将绑定到所有网络接口,以便您可以使用计算机的

引用以下规范:

如果指定了
AI_PASSIVE
标志,则返回的地址信息应适用于绑定套接字以接受指定服务的传入连接。在这种情况下,如果
nodename
参数为空,则套接字地址结构的IP地址部分对于IPv4地址应设置为
INADDR\u ANY
,对于IPv6地址应设置为
INADDR\u ANY\u INIT

这是有道理的。如果指定
AI\u PASSIVE
,则可以在返回的地址上
bind()
/
listen()
/
accept()
。如果
nodename
为空,则返回的地址将绑定到所有网络接口,以便您可以使用计算机的任何IP地址(例如以太网LAN IP、Wi-Fi LAN IP、环回地址等)。摘要:在服务器上使用
AI_PASSIVE
(用于TCP套接字)

继续:

如果未指定
AI_PASSIVE
标志,则返回的地址信息应适用于调用
connect()
(对于连接模式协议)或调用
connect()
sendto()
sendmsg()
(对于无连接协议)。在这种情况下,如果
nodename
参数为空,则套接字地址结构的IP地址部分应设置为环回地址

这也是有道理的。如果您没有指定
AI_PASSIVE
,您可以
connect()
/
sendto()
/
sendmsg()
。如果
nodename
为空,则获得环回地址。小结:不要在客户端上使用
AI_PASSIVE
(对于TCP套接字)

继续:

如果
nodename
参数不为空,则应忽略
AI_PASSIVE
标志

嗯?忽略
AI_被动
标志意味着什么?从前两个引号中可以看出,
AI_PASSIVE
仅用于确定您是否获得适合服务器/客户端使用的地址,在这两种情况下,它听起来都像是空的
nodename
只会给您一个
INADDR_ANY
地址(用于服务器)或环回地址(用于客户端)。忽略
AI_被动
标志有什么好处


最后一句话的真正含义是什么?它是如何影响前两个引号的?

gettaddrinfo(2)的Linux手册页对它的描述略有不同(而且更一致):

如果在hints.AI_标志中指定了AI_PASSIVE标志,并且节点为空,则返回的套接字地址将适用于绑定将接受连接的套接字。返回的套接字地址将包含“通配符地址”[…]。如果node不为NULL,则忽略AI_PASSIVE标志

如果在hints.AI_标志中未设置AI_被动标志,则返回的套接字地址将适合与连接(2)、发送(2)或发送消息(2)一起使用。如果节点为空,则网络地址将设置为环回接口地址[…]

当然,除了Linux之外,Linux手册页并不具有权威性,但我提供它作为一种广泛使用的解释。特别要注意的是,它指定仅当AI_PASSIVE被指定为并且节点为NULL时,才获得服务器套接字。对于“忽略”AI_PASSIVE意味着什么,这仍然存在一些模糊性,但我认为它指向了Linux所采取的解释:如果节点不为NULL,您总是可以获得适合客户端套接字的地址信息


你也许可以这样解释:“AI_被动标志应该被忽略”应该解释为“如果设置了AI_被动标志,那么这个事实应该被忽略”。也就是说,应将其视为未设置标志。我认为这一点还得到了一个事实的支持,即这一陈述与设置AI_PASSIVE时的行为描述在同一段中(在官方文档中,而不仅仅是Linux手册页中)。

总之,
AI\u PASSIVE
唯一有用的时候是当您创建一个服务器套接字并希望它绑定到所有接口时(因此您将
NULL
传递给
nodename
)?那有点蹩脚。与直接在6addr\u ANY\u INIT中使用
INADDR\u ANY
/
相比,它究竟有什么用处?
getaddrinfo()
填充其他字段,而不仅仅是IP地址。因此,将
getaddrinfo()
与NULL
nodename
一起使用仍然很有用,而不是手动填充
sockaddr
。如果
nodename
不为NULL,并且未指定
AI_numerihost
,则执行DNS查找。对于被动监听插座,这样做是没有意义的。另一方面,如果
nodename
是一个IP地址,并且指定了
AI\u numericost
,那么无论是否指定了
AI\u PASSIVE
,IP地址都会按原样返回,并且可以同样用于
bind()
connect()
sendto()
,等等,
getaddrinfo()
不在乎。记住,
AI_PASSIVE
只是一个提示,它并不适用于所有情况。