connect()使用ipv6地址返回“invalid argument”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了connect()使用ipv6地址返回“invalid argument”相关的知识,希望对你有一定的参考价值。

我有这个简单的客户端 - 服务器应用程序对。代码很简单,我只使用新的,建议的方法,如getaddinfo等,一切都适用于ipv4。即使对于ipv6 loopback(:: 1)也适用。当涉及到其他一些ipv6地址时出现问题...我在网络中有两台机器,当我传递他们的ipv4地址时一切正常,但是当我给我的客户端ipv6地址时,我在连接函数上出错:无效参数。嘿,我不知道这个吗?我做!当我尝试ping这个ipv6地址时,我得到同样的错误:

connect:参数无效

但是有一种方法可以克服这个障碍 - 应该选择一个带-I开关的接口,从那时起它就会顺利运行。但是如何在我的客户端应用程序中实现相同的目标?我该怎么办?我的客户端代码如下所示:

struct addrinfo hints;
struct addrinfo *server;

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

int status;
if((status = getaddrinfo(argv[1], argv[2], &hints, &server) != 0))
{
    perror("getaddrinfo error");
    return 1;
}

int sock_fd;
struct addrinfo *ptr;
for(ptr=server;ptr!=NULL;ptr=ptr->ai_next)
{
    if( (sock_fd = socket(ptr->ai_family,ptr->ai_socktype,ptr->ai_protocol)) == -1)
    {
        perror("socket error");
        continue;
    }
    if( connect(sock_fd, ptr->ai_addr,ptr->ai_addrlen) == -1 )
    {
        perror("connect error");
        continue;       
    }
    break;
}
答案

ff...开头的地址是多播地址。将流连接到多播地址不起作用。

fe80...开头的地址是链接本地地址,它们具有与之关联的接口标识符。试着看看从sockaddr回来的getaddrinfo,是填写的scope字段吗?

另一答案

您需要指定IPv6 ping的接口(即-I eth0):

ping6 -I eth0 fe80::208:54ff:fe34:22ae

使用链路本地地址进行IPv6 ping,需要定义必须发送/接收数据包的设备 - 每个设备都有一个链路本地地址。

尝试没有这个,将导致错误消息,如:

--> # ping6 fe80::208:54ff:fe34:22ae 
connect: Invalid argument

在这种情况下,您必须另外指定界面,如下所示:

--> # ping6 -I eth0 fe80::208:54ff:fe34:22ae
PING fe80::208:54ff:fe34:22ae(fe80::208:54ff:fe34:22ae) from fe80::208:54ff:fe34:22ae eth0: 56 data bytes
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=0 ttl=64 time=0.027 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=2 ttl=64 time=0.036 ms

您必须在客户端APP中遵循一种类似的方法..

另一答案

我的建议是你在接口/网络连接中打开IP6协议,另外如果你还有错误就扔掉ip4协议。

在我的Linux Box上,当我的ip4接口处于活动状态并且我的应用程序尝试使用ip4接口和ip6设置时,这也发生了。同样也应该对Windows有效。

如果有什么不明确的问题。

以上是关于connect()使用ipv6地址返回“invalid argument”的主要内容,如果未能解决你的问题,请参考以下文章

nginx实现Ipv6地址解析

判断IPv6地址合法性

Dns.GetHostAddress和Dns.GetHostEntry都只返回ipv4地址。我如何获得ipv4和ipv6地址?

在 OSX 上具有“嵌入式”范围的 IPv6 链接本地地址

Code-Validator:验证IPv6地址

iOS ipv6