我想为我的程序添加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
/列表的末尾)。