【发布时间】:2026-02-22 02:00:01
【问题描述】:
我正在查看一些过时的代码,这些代码使用 getaddrinfo 和 getnameinfo 来确定主机名信息,然后在 getnameinfo 失败时回退到 gethostname 和 gethostbyname。
现在,这对我来说似乎是错误的。我正在尝试了解代码的意图,以便提出建议。我不想在这里重新发布整个代码,因为它又长又复杂,但我会尝试总结一下:
据我所知,这段代码的重点是生成一个字符串,另一个进程可以使用该字符串连接到侦听套接字。这似乎不仅适用于本地进程,也适用于远程主机连接回这台计算机。
所以有问题的代码基本上是在做以下事情:
-
getaddrinfo(node = NULL, service = port, hints.ai_flags = AI_PASSIVE, ai);-- 这将获取socket()的可能参数列表,这些参数可以与bind()一起使用。 - 浏览结果列表并创建一个套接字。
- 第一次成功创建套接字时,将其选为“已使用”
addrinfo。 - 对于选中的
addrinfo中的ai_addr,调用getnameinfo()获取关联的主机名。 - 如果失败,请致电
gethostname(),然后在结果中查找gethostbyname()。
我认为这是错误的有几个原因,但我想验证我的逻辑。首先,从一些实验看来,getnameinfo() 在这里几乎总是失败。我想输入地址是未知的,因为它是一个监听套接字,而不是一个目的地,所以从这个角度来看,它不需要一个有效的 IP。然后,调用gethostname() 并将结果传递给gethostbyname() 几乎总是返回与gethostname() 本身相同的结果。换句话说,它只是验证本地主机名,对我来说似乎毫无意义。这是有问题的,因为它甚至不一定能被远程主机使用,不是吗?
不知何故,我认为尝试在子网上确定您自己的主机名的整个想法可能不是那么有用,而是您必须向另一台主机ping 一条消息并查看他们认为它是什么IP 地址。 (不幸的是,在这种情况下这没有意义,因为我不知道该程序级别的其他对等方。)例如,本地主机可能有多个 NIC,因此有多个 IP 地址,因此尝试确定单个主机地址对是无意义的。 (仅bind() 并同时收听所有 addrinfo 结果是否正确?)
我还注意到,只需将名称传递给getaddrinfo() 并设置AI_CANONNAME 标志即可解析名称,这意味着getnameinfo() 步骤可能是多余的。但是,我想这里没有这样做,因为他们试图在不提供先验信息的情况下确定主机名的某种公正视图。当然,它失败了,他们最终还是使用了gethostname()!我还尝试向getaddrinfo() 提供“localhost”,它会在 ai_canonname` 中报告 Linux 下的主机名,但在 OS X 上只会导致“localhost”,所以它不是那么有用,因为这应该是跨平台的。
我想总结一下,我的问题是,在现代套接字编程中,正确方法是什么?我倾向于用简单地返回 gethostname() 的结果来替换这段代码,但我想知道是否有更合适的解决方案使用像 getaddrinfo() 这样的现代调用。
如果答案是没有办法做到这一点,我只能使用gethostname(),因为我必须在这里返回一些东西,否则会破坏 API。
【问题讨论】:
标签: sockets