当前位置: 首页 > 知识库问答 >
问题:

将IPv4客户端连接到IPv6服务器:连接被拒绝

司徒博容
2023-03-14
addrinfo* result, *pCurrent, hints;

memset(&hints, 0, sizeof hints);    // Must do this!
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;     // We intend to use the addrinfo in a call to connect().  (I know it is ignored if we specify a server to connect to...)

int nRet = getaddrinfo("powerhouse", "82", &hints, &result);

SOCKET sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

int no = 0;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) != 0)
    return -1;

if (bind(sock, result->ai_addr, result->ai_addrlen) ==  SOCKET_ERROR)
    return -1;

if (listen(sock, SOMAXCONN) == SOCKET_ERROR)
    return -1;

SOCKET sockClient = accept(sock, NULL, NULL);
addrinfo* result, *pCurrent, hints;

memset(&hints, 0, sizeof hints);    // Must do this!
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;

if (getaddrinfo("powerhouse", "82", &hints, &result) != 0)
    return -1;

SOCKET sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
int nRet = connect(sock, result->ai_addr, result->ai_addrlen);

我的connect调用的结果始终是10061:连接被拒绝。

如果我将服务器代码更改为绑定到::(或者将空主机传递给getaddrinfo()(同样的事情)),并将客户机代码更改为在getaddrinfo()调用中指定空主机,那么V4客户机可以很好地连接。

谁能解释一下为什么?我没有读到任何东西,如果我们想要双套接字行为,我们必须指定一个空主机(因此使用INADDR_ANY)。这不可能是一个要求,因为我有一个多宿主主机,并且我只想在一些可用的IP上接受IPv4?

“默认情况下,在Windows Vista及更高版本上创建的IPv6套接字仅在IPv6协议上运行。为了使IPv6套接字成为双堆栈套接字,必须使用IPV6_V6ONLY套接字选项调用setsockopt函数,以便在套接字绑定到IP地址之前将此值设置为零。当IPV6_V6ONLY套接字选项设置为零时,可以使用为AF_INET6地址族创建的套接字向IPv6地址或IPv4映射地址发送数据包和从IPv6地址或IPv4映射地址接收数据包。(重点是我的)”

共有1个答案

殷宾白
2023-03-14

IPv4和IPv6是两个独立的协议。一种协议的数据包不能使用另一种协议处理。这就是双栈概念存在的原因:您的系统同时运行IPv4和IPv6协议栈,同时拥有IPv4和IPv6地址,等等。

操作系统有一个诀窍,你可以有一个IPv6套接字侦听所有的IPv4和IPv6地址。您仍然需要在主机上同时拥有这两个地址族,并且只有在绑定到通配符地址时才起作用。一旦您将套接字绑定到一个固定地址,它就不再起作用了,它只对您绑定到的地址起作用。

因此,如果您想侦听所有可用地址,那么将IPV6_V6ONLY设置为0并侦听通配符地址就可以了。IPv4客户端将显示为使用以::ffff:开头的IPv6地址,最后32位包含IPv4地址。

 类似资料:
  • 每次运行Rails4.0服务器时,都会得到这个输出。 我正在运行小牛OS X10.9,所以我不知道这是不是问题所在。我已经试了我能试的一切,但似乎都没有效果。我已经卸载并安装了postgres和pg gem多次了。 这是我的database.yml文件

  • 我正在尝试运行https://github.com/hazelcast/hazelcast-nodejs-client的“使用客户端”部分中提供的基本示例代码 我收到连接拒绝错误。我在我的Mac和PC机器上尝试了这个,结果相同。它们运行的是Node v6.9.1。我没有任何特殊的防火墙设置。甚至尝试完全打开Windows防火墙。 我错过了什么吗? 首先,我创建了一个空节点项目,然后: 然后创建了一

  • 我有一个示例Spring启动应用程序来运行图形QL服务器,具有作为客户端,我的pom有以下依赖项: 当我尝试从客户端连接时,出现以下错误: 狩猎决议好心建议。 我还有几个问题: 我应该使用SimpleGraphQLHttpServlet将请求路由到endpoint吗 我正在React UI上使用apollo client,那么它是强制使用apollo server还是spring boot可以工作

  • 问题内容: 我正在尝试使用Flask在Raspberry Pi上运行一个简单的Web服务器。当我运行Flask应用程序时,它说: 在http://127.0.0.1:5000/上运行 但是,当我在笔记本电脑的Chrome中输入此地址时, ERR_CONNECTION_REFUSED 我可以在Raspberry Pi的浏览器上打开127.0.0.1:5000。我需要怎么做才能从另一台计算机连接? 问

  • 客户端应用程序在以下代码处挂起:

  • 下面是我的服务器代码: 下面是我的客户端活动代码: 以下是客户端活动的xml布局文件: 因此,我开始认为这不是连接端口的问题,而是应用程序的android客户端的问题。但我想不出有什么问题。 顺便说一下,当我试图发送消息时,运行客户端的手机和运行服务器的笔记本电脑都连接到了同一个网络。