我在Linux主机上设置了一个双堆栈,并试图连接到一个可以监听in6addr_loopback或in6addr_any的TCP/IPv6 6服务器,下面是服务器的一个非常小的例子:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
if (argc != 2)
exit(1);
struct sockaddr_in6 serv6;
memset(&serv6, 0, sizeof(struct sockaddr_in6));
int fd6 = socket(AF_INET6, SOCK_STREAM, 0);
int loopback = atoi(argv[1]);
if (loopback)
serv6.sin6_addr = in6addr_loopback;
else
serv6.sin6_addr= in6addr_any;
serv6.sin6_port = htons(3000);
serv6.sin6_family = AF_INET6;
int opt = 1;
setsockopt(fd6, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
if (bind(fd6, (struct sockaddr *)&serv6, sizeof(struct sockaddr_in6)) < 0) {
perror("bind");
exit(1);
}
listen(fd6, 5);
int cli = accept(fd6, NULL, NULL);
char buf[10] = {0};
int n = read(cli, buf, 9);
if (n > 0)
fprintf(stderr, "received %d bytes : %s from ipv6 stack\n", n, buf);
else
perror("read");
exit(0);
}我在同一台主机上使用ncat以下列方式连接到服务器:
服务器正在监听in6addr_any:
ncat 127.0.0.1 3000 // OK
ncat ::1 3000 // OK
ncat ::ffff:127.0.0.1 3000 // OK服务器正在监听in6addr_loopback
ncat 127.0.0.1 3000 // Ncat: Connection refused.
ncat ::1 3000 // OK
ncat ::ffff:127.0.0.1 3000 // Ncat: Connection refused.为什么它只适用于环回接口的IPv6地址?谢谢。
发布于 2022-11-29 22:07:26
若要在双堆栈侦听套接字上同时接受IPv4和IPv6客户端,应在对套接字进行bind()‘处理之前,通过setsockopt()显式禁用IPV6_V6ONLY选项。
但是,更重要的是,绑定到in6addr_any (::0)的双堆栈套接字将绑定到所有本地IPv4 和 IPv6接口,而绑定到in6addr_loopback (::1)的双堆栈套接字只能绑定到IPv6回送接口,而不能绑定到IPv4回送接口(即::1 != 127.0.0.1)。
https://stackoverflow.com/questions/74617854
复制相似问题