我正在尝试编写一个侦听 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_INETAF_INET6getaddrinfoAF_INET6
我试图通过设置来解决这个问题hints.ai_family = AF_INET6,但在 IPv6 不可用的系统上失败了。
我看到了两个明显的解决方案:
a)尝试首先请求 IPv6,如果失败则回退到 IPv4,或者
b)遍历结果getaddrinfo,查找 IPv6,如果不存在,则选择第一个条目
,但我不喜欢要么一个太多;)我觉得应该有一种方法来说服getaddrinfo做正确的事情,或者可能是一种不同的方法来实现我的目标。