我如何将套接字绑定到ipv6地址?

问题描述 投票:3回答:2

我正在尝试将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
c++ server bind ipv6
2个回答
1
投票

这可能取决于您的平台,但是在Linux上,从2.4开始,sockaddr_in6结构还包含用于定义IPv6范围的sin6_scope_id成员,并且由于变量hint在堆栈中,因此其中包含随机数据。

IPv6范围描述了它是一种什么样的地址:单播,多播,本地链接和其他一些地址,而我对它们只有一个了解。但是,如果那里有垃圾,那可能是一件事。

[建议通过将sin6_scope_id硬设置为零,或者(最好)在将整个sockaddr_in6结构分配给对象之前,最好将其归零来解决这个问题;我很早就使用sockaddr_in变量来完成此操作,只是为了确保我不会遇到我不想要的垃圾。

memset(&hint, 0, sizeof hint);

是,errno非常重要。


1
投票

而不是手动填充sockaddr_in6,您可以(并且应该)改用getaddrinfo(),并让它为您分配正确填充的getaddrinfo(),例如:

sockaddr_in6
© www.soinside.com 2019 - 2024. All rights reserved.