Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建IPv6套接字失败,IP无效-似乎被截断 我目前正在学习C++,我正在开发一个允许在Windows和Linux上创建套接字的库,支持IPv4和IPv6。p>_C++_Sockets - Fatal编程技术网

创建IPv6套接字失败,IP无效-似乎被截断 我目前正在学习C++,我正在开发一个允许在Windows和Linux上创建套接字的库,支持IPv4和IPv6。p>

创建IPv6套接字失败,IP无效-似乎被截断 我目前正在学习C++,我正在开发一个允许在Windows和Linux上创建套接字的库,支持IPv4和IPv6。p>,c++,sockets,C++,Sockets,我在IPv4上工作得很好,但我在IPv6上遇到了问题 我尝试过这样做,它绑定到一个IP地址或绑定到一个特定的IPV6地址,但要么失败 下面是我如何创建套接字的 this->serverSocket = socket(family, socketType, 0); if (this->serverSocket < 0) { stringstream logstream; logstream <&

我在IPv4上工作得很好,但我在IPv6上遇到了问题

我尝试过这样做,它绑定到一个IP地址或绑定到一个特定的IPV6地址,但要么失败

下面是我如何创建套接字的

this->serverSocket = socket(family, socketType, 0);
        if (this->serverSocket < 0)
        {
            stringstream logstream;
            logstream << "Error opening socket. Most likely trying to bind to an ";
            logstream << "invalid IP or the port is already in use";
            bitsLibrary->writeToLog(logstream.str(), "LinuxSocket", "createSocket");
            return false;
        }

        switch (family)
        {
            case AF_INET: {
                this->serv_addr = new sockaddr();
                bzero((sockaddr*)this->serv_addr, sizeof(this->serv_addr));
                sockaddr_in *sin = reinterpret_cast<sockaddr_in*>(serv_addr);
                sin->sin_family = family;
                //sin->sin_addr.s_addr = INADDR_ANY;
                //If IP Address is NULL then set to IPADDR_ANY
                if (ipAddress.empty())
                {
                    sin->sin_addr.s_addr = INADDR_ANY;
                }
                else
                {
                    inet_pton(AF_INET, ipAddress.c_str(), &sin->sin_addr);
                }
                sin->sin_port = htons(port);
                break;
            }
            case AF_INET6: {
                this->serv_addr = new sockaddr();
                bzero((sockaddr*)this->serv_addr, sizeof(this->serv_addr));
                sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(serv_addr);
                sin->sin6_family = family;
                if (ipAddress.empty())
                {
                    sin->sin6_addr = IN6ADDR_ANY_INIT;
                }
                else
                {
                    inet_pton(AF_INET6, ipAddress.c_str(), &(sin->sin6_addr));
                }
                sin->sin6_port = htons(port);
                break;
            }
            default:
                this->bitsLibrary->writeToLog("Invalid socket family. Only AF_INET or AF_INET6 is supported");
                return false;
        }
绑定返回-1 strerror表示发生未知错误

我传递到createSocket方法的IP地址是
fe80::20c:29ff:fea0:7da8

当我通过strace运行我的程序时,我会在绑定上得到以下内容

socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 4
bind(4, {sa_family=AF_INET6, sin6_port=htons(500), inet_pton(AF_INET6, "fe80::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 16) = -1 EINVAL (Invalid argument)
请注意,IP已被截断为
fe80::

如果我不使用IP,那么它会绑定到任何IP,然后

更新 下面是我为AF_INET6套接字更改的代码

case AF_INET6: {
                this->serv_addr = new sockaddr_storage();
                bzero((sockaddr_in6*)this->serv_addr, sizeof(this->serv_addr));
                sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(serv_addr);
                sin->sin6_family = family;
                if (ipAddress.empty())
                {
                    sin->sin6_addr = IN6ADDR_ANY_INIT;
                }
                else
                {
                    inet_pton(AF_INET6, ipAddress.c_str(), &sin->sin6_addr);
                }
                sin->sin6_port = htons(port);
                break;
}
案例6:{
此->serv_addr=new sockaddr_storage();
bzero((sockaddr_in6*)this->serv_addr,sizeof(this->serv_addr));
sockaddr\u in6*sin=重新解释强制转换(serv\u addr);
sin->sin6_family=family;
if(ipAddress.empty())
{
sin->sin6\u addr=IN6ADDR\u ANY\u INIT;
}
其他的
{
inet\u pton(AF\u INET6,ipAddress.c\u str(),&sin->sin6\u addr);
}
sin->sin6_端口=htons(端口);
打破
}

我还更改了此->servAddr is sockaddr\u存储在标题中的建议,至少在Windows上,
sizeof(sockaddr)
。当您为
this->serv\u addr
分配内存时,分配的内存不足,然后损坏堆块,然后出现错误

建议您使用
sockaddr\u存储
,它“足够大,可以容纳所有支持的特定于协议的地址结构”。或者,您可以在不同的情况下分配不同的结构,这对于代码的其余部分来说应该不是问题

更新1

您的代码中似乎仍有一些错误。您需要检查对
this->serv\u addr
的所有引用,并验证类型/sizeof

--示例1:您
bzero()

bzero((sockaddr_in6*)this->serv_addr, sizeof(this->serv_addr));
应该这样固定:

sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(serv_addr);
bzero(sin, sizeof(*sin));

您应该在分配时记住
this->serv\u addr
的实际大小,并将此大小传递给
bind()

至少在Windows上,
sizeof(sockaddr)
。当您为
this->serv\u addr
分配内存时,分配的内存不足,然后损坏堆块,然后出现错误

建议您使用
sockaddr\u存储
,它“足够大,可以容纳所有支持的特定于协议的地址结构”。或者,您可以在不同的情况下分配不同的结构,这对于代码的其余部分来说应该不是问题

更新1

您的代码中似乎仍有一些错误。您需要检查对
this->serv\u addr
的所有引用,并验证类型/sizeof

--示例1:您
bzero()

bzero((sockaddr_in6*)this->serv_addr, sizeof(this->serv_addr));
应该这样固定:

sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(serv_addr);
bzero(sin, sizeof(*sin));

您应该记住分配时
this->serv\u addr
的实际大小,并将此大小传递给
bind()

Hmm,它已取得进展,现在可以绑定到任何地址(虽然无法通过ip6地址本地连接到它,但只能从远程计算机上工作,但如果我指定了IP地址,它在更新代码时仍会在屏幕上显示EINVAL,以便我可以看到更改。例如,不确定是否已修复
sizeof(*serv\u addr)
。此外,我建议您在
create()中使用IPPROTO\u TCP)
相反,如果为0。我传递到绑定中的缓冲区大小有什么问题,我在网上看到的所有内容似乎都与我拥有的内容相匹配,唯一的区别是我正在取消引用,因此它不是预期的指向结构的指针。它必须与
serv\u addr
的实际大小相匹配。对于IPv6,它将是
sizeof(sockaddr\u in6)
。分配时,您需要记住
serv\u addr
的大小。好的,我已经尝试过了。我找到了需要设置
sin6\u scope\u id
的东西,我使用
sin->sin6\u scope\u id=if\u nametoindex(“eno16777728”);
现在我得到了
EADDRNOTAVAIL(无法分配请求的地址)
。不确定这是否正在进行中mm,它已经进行了,现在可以绑定到任何地址(虽然无法通过ip6地址本地连接到它,但只能从远程计算机上工作,但如果我指定了IP地址,它在更新代码时仍会在屏幕上显示EINVAL,以便我可以看到更改。例如,不确定是否已修复
sizeof(*serv\u addr)
。此外,我建议您在
create()中使用IPPROTO\u TCP)
相反,如果为0。我传递到绑定中的缓冲区大小有什么问题,我在网上看到的所有内容似乎都与我拥有的内容相匹配,唯一的区别是我正在取消引用,因此它不是预期的指向结构的指针。它必须与
serv\u addr
的实际大小相匹配。对于IPv6,它将是
sizeof(sockaddr\u in6)
。分配时,您需要记住
serv\u addr
的大小。好的,我已经尝试过了。我找到了需要设置
sin6\u scope\u id
的东西,我使用
sin->sin6\u scope\u id=if\u nametoindex(“eno16777728”);
现在我得到了
EADDRNOTAVAIL(无法分配请求的地址)
。不确定这是否有进展
int result = bind(this->serverSocket, (sockaddr * )serv_addr, sizeof(*serv_addr));