【问题标题】:getaddrinfo: in what way is AI_PASSIVE ignored if the nodename is specified?getaddrinfo:如果指定了节点名,AI_PASSIVE 以什么方式被忽略?
【发布时间】:2015-03-05 22:15:10
【问题描述】:

引用getaddrinfo的规范:

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

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

继续:

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

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

继续:

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

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

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

【问题讨论】:

    标签: c++ c sockets networking posix


    【解决方案1】:

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

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

    如果 hints.ai_flags 中没有设置 AI_PASSIVE 标志,则返回的套接字地址将适用于 connect(2 )、sendto(2) 或 sendmsg(2)。如果 node 为 NULL,则网络地址将设置为环回接口地址 [...]。

    当然,Linux 联机帮助页除了 Linux 之外没有权威性,但我将其作为广泛使用的解释提供。特别要注意,它指定只有当 AI_PASSIVE 被指定 并且 node 为 NULL 时,您才能获得服务器套接字。对于“忽略”AI_PASSIVE 的含义,这仍然存在一些歧义,但我认为它仍然指向 Linux 所采取的解释:如果 node 不是,您总是会获得适合客户端套接字的地址信息空。

    您或许可以这样解释:“AI_PASSIVE 标志应被忽略”应解释为“如果设置了 AI_PASSIVE 标志,则该事实应被忽略”。即,它应该被当作没有设置标志来处理。我认为这一点还得到了以下事实的支持:该语句与设置 AI_PASSIVE 时的行为描述出现在同一段落中(也在官方文档中,而不仅仅是 Linux 手册页)。

    【讨论】:

    • 所以,总而言之,AI_PASSIVE 唯一有用的时候是当你创建一个服务器套接字并希望它绑定到所有接口时(所以你会传入@987654323 @ 代表nodename)?这有点蹩脚。与直接使用 INADDR_ANY/IN6ADDR_ANY_INIT 相比,它到底为什么会有用?
    • getaddrinfo() 填充其他字段,而不仅仅是 IP 地址。因此,将getaddrinfo() 与NULL nodename 一起使用而不是手动填充sockaddr 仍然很有用。
    • 如果 nodename 不为 NULL,并且未指定 AI_NUMERICHOST,则执行 DNS 查找。对于被动侦听套接字这样做是没有意义的。另一方面,如果nodename是IP地址,并且指定了AI_NUMERICHOST,则不管AI_PASSIVE是否指定,IP地址都按原样返回,同样可以用于bind()connect()sendto() 等,getaddrinfo() 不在乎。请记住,AI_PASSIVE 只是一个提示,它并不适用于所有事情。
    猜你喜欢
    • 2021-06-27
    • 2022-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多