我正在尝试编写一个侦听 IPv6 和 IPv4 连接的服务器应用程序。完成此任务的正确方法似乎是侦听 IPv6 地址,该地址也将接受 IPv4 连接。
相关的代码是:
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, MYPORT, &hints, &res);
(几乎从 Beej's Guide 复制粘贴)
问题是,至少在我的系统上,返回第一个和第二个getaddrinfo
条目- 而客户端的返回首先,根据规范。用我天真的方法,服务器选择 IPv4,客户端选择 IPv6,连接失败。AF_INET
AF_INET6
getaddrinfo
AF_INET6
我试图通过设置来解决这个问题hints.ai_family = AF_INET6
,但在 IPv6 不可用的系统上失败了。
我看到了两个明显的解决方案:
a)尝试首先请求 IPv6,如果失败则回退到 IPv4,或者
b)遍历结果getaddrinfo
,查找 IPv6,如果不存在,则选择第一个条目
,但我不喜欢要么一个太多;)我觉得应该有一种方法来说服getaddrinfo
做正确的事情,或者可能是一种不同的方法来实现我的目标。