当源使用IPv6监听时,无法连接回环地址

3

我有一台服务器正在监听一个端口。

sockfd = socket(PF_INET6,SOCK_STREAM,IPPROTO_TCP);
memset(&addr,0,len = sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(2000);
addr.sin6_flowinfo = 0;
addr.sin6_scope_id = 0;
addr.sin6_addr = in6addr_any;

bind(sockfd,(struct sockaddr*)&addr,len);
listen(sockfd,4);

它正在等待接受。
.....    
socket = accept(sockfd,(struct sockaddr*)&addr,&len);

我用 netstat -tan 命令看到了 "tcp 0 0 :::2000 :::* LISTEN "。
我有一个客户端试图连接该服务器,但是出现了错误 connect() failure, Connection refused。
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(2000);

if ((sockfd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1)
     printf("ERROR opening socket\n");

memset(buffer,0x00,sizeof(buffer));

我在这里填充缓冲区。

if (connect(sockfd,(struct sockaddr *)&addr,sizeof(addr)) < 0)
 printf("connect() failure, %s-\n", strerror(errno));

我可以使用telnet连接xx.xx.xx.xx的2000端口。这段代码有什么问题?
1个回答

0

要连接到IP6服务器,客户端应尝试建立IP6连接。

因此,您可能想要更改此内容:

addr.sin_family = AF_INET;
addr.sin_port = htons(2000);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

成为:

addr.sin6_family = AF_INET6;
addr.sin6_port = htons(2000);
addr.sin6_addr = in6addr_loopback;

telnet客户端可能在内部使用getaddrinfo()来查询通过telnet命令行给出的IP4地址指定的主机是否有可用的IP6服务。


顺便提一下: bind()connect() 的最后一个参数是socklen_t类型。 accept() 的最后一个参数是socklen_t *类型。

在服务器端,它接受bot v4和v6连接。我在服务器上监听了四个端口,其中三个没有问题。我可以使用v4连接它们,但只有这个端口有问题。我使用cgic并从Web调用cgi,但失败了。我查看了Wireshark并发现它发送消息到代码中未提及且未被监听的不同端口。 - brknl
在打开套接字之前,我在顶部填充了缓冲区,然后错误变成了“网络不可达”。我将addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);更改为addr.sin_addr.s_addr = inet_addr("127.0.0.1");然后“连接被拒绝”的错误又出现了。 - brknl
1
主机字节顺序是否与网络字节顺序不同,取决于代码运行的平台的字节序。例如,对于x86,它是不同的,而对于PowerPC,它是相同的。网络字节顺序为大端字节序。请参见此处了解更多信息:http://en.wikipedia.org/wiki/Endianness @brknl - alk
1
你可能想在你的 OP 中说明如何声明 addr。@brknl - alk
欢迎您。如果您自己找到了与其他人给出的答案不同的答案,您可以自己添加一个答案来回答您的问题。这样可以让后来的读者看到问题是如何解决的。如果其他人给出了合适的答案,您可以自由地点赞并选择其中一个作为最佳答案。@brknl - alk
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接