来自socket()调用的错误

我想为我的程序添加IPv6支持,并遇到奇怪的错误。 我想打开接受连接的套接字。 这是我的情况:

首先我使用getaddrinfo()来查找套接字configuration:

struct addrinfo hint, *info = NULL; memset((void *)&hint, 0, sizeof(hint)); hint.ai_family = AF_INET6; hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; hint.ai_socktype = SOCK_STREAM; if ((error = getaddrinfo(NULL, "1234", &hint, &info))) { /* some error handling */ } 

我在info产生非NULL结果。 然后我想创build套接字:

 socket(info->ai_family, info->ai_socktype, info->ai_protocol) 

这里我得到-1

 strerror(errno) 

返回Address family not supported by protocol

我认为getaddrinfo()只返回可以绑定的地址,我期望它在这种情况下返回NULL。 我错过了什么?

我想补充说我的eth0目前没有IPv6地址。 我正在使用uClibc 0.9.32

您需要将AI_ADDRCONFIG添加到ai_flags,以确保它不返回内核不支持的地址族。 我现在几乎总是添加那个标志。

如果你想支持没有IPv6的内核,你必须避免将ai_family设置为AF_INET6。 相反,您必须监听所有返回的地址,并确保在AF_INET6上设置IPV6_V6ONLY。 不幸的是,不能保证AF_INET6地址会先被返回。

getaddrinfo返回一个struct addrinfo对象的链表,你可以使用ai_next成员遍历它。 你应该依次尝试每一个返回的addrinfo对象,直到你得到一个连接(或者命中NULL /列表的末尾)。