我正在尝试将ipv4应用程序移植到ipv6,但是我无法将套接字绑定到ipv6地址。
问题在这里:
err=bind(listening, (sockaddr*)&hint, sizeof(hint));
err
应该为0,但在此代码中它返回-1。怎么了?
SOCKET listening = socket(AF_INET6, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! Quitting" << endl;
return;
}
int err;
// Bind the ip address and port to a socket
sockaddr_in6 hint;
hint.sin6_family = AF_INET6;
hint.sin6_flowinfo = 0;
hint.sin6_port = htons(54000);
hint.sin6_addr = in6addr_any;
err=bind(listening, (sockaddr*)&hint, sizeof(hint)); //<======= here
这可能取决于您的平台,但是在Linux上,从2.4开始,sockaddr_in6
结构还包含用于定义IPv6范围的sin6_scope_id
成员,并且由于变量hint
在堆栈中,因此其中包含随机数据。
IPv6范围描述了它是一种什么样的地址:单播,多播,本地链接和其他一些地址,而我对它们只有一个了解。但是,如果那里有垃圾,那可能是一件事。
[建议通过将sin6_scope_id
硬设置为零,或者(最好)在将整个sockaddr_in6
结构分配给对象之前,最好将其归零来解决这个问题;我很早就使用sockaddr_in
变量来完成此操作,只是为了确保我不会遇到我不想要的垃圾。
memset(&hint, 0, sizeof hint);
是,errno
非常重要。
而不是手动填充sockaddr_in6
,您可以(并且应该)改用getaddrinfo()
,并让它为您分配正确填充的getaddrinfo()
,例如:
sockaddr_in6