2012-09-04 77 views
6

我有这个简单的客户端 - 服务器应用程序对。代码很简单,我只使用新的建议的方法,如getaddinfo等,一切工作正常的ipv4。即使对于ipv6 loopback(:: 1)也是如此。问题开始涉及到其他ipv6地址...我有两台机器在网络中,一切正常,当我通过他们的ipv4地址,但当我给我的客户ipv6地址,我得到一个连接函数的错误:无效参数。 嘿,我不知道这个?我做!当我尝试ping6这个IPv6地址,我得到了同样的错误:connect()返回“无效参数”与ipv6地址

connect: Invalid argument

但是有一个方法来克服此块 - 应该选择一个-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; 
} 
+1

这是ping拒绝的有问题的地址是什么? – Ariel

+0

我在ping我的网络中的其他机器,但它对所有ipv6地址的作用相同 - 请检查: http://lists.debian.org/debian-ipv6/2005/06/msg00044.html – flyjohny

+0

@flyjohny也许你应该检查你的路线看看是否默认路由是一个ip6路由命令:“route -A inet6” –

回答

5

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

fe80...的地址是链路本地地址,它们具有与其相关联的接口标识符。试试看从getaddrinfo返回,是scope字段填写?

+0

它被填充0.地址确实以fe80开头...... – flyjohny

+2

该字段应包含接口号。你是否用'%eth0'或'%1'指定了范围(1是接口号,你可以用'ip'工具查找)符号?\ –

+0

不可以。当我这样做时,这个范围字段充满了一些价值,它似乎工作(虽然我需要配置我的具体固件,但我没有得到任何无效论点)。 但我似乎错过了所有与ipv6相关的资料我正在读我没有遇到过这种情况 - 我需要指定接口,每当我使用链接本地地址? – flyjohny

0

我的建议是,你打开的接口/网络连接IP6的协议,除了扔出去的ip4的协议,如果你仍然有错误。

在我的Linux机箱上,当我有一个ip4接口活动并且我的应用程序试图使用ip4接口和ip6设置时,也发生了这种情况。对于Windows也一样。

如果有什么不明确的问。

+0

我知道我是懒惰的屁股,但你能告诉我如何打开接口中的ip6协议?我正在使用Linux机器。 – flyjohny

+0

首先查看本指南http://tldp.org/HOWTO/Linux+IPv6-HOWTO/x790。html之后,请在您的特定界面上尝试以下操作:ping6 -I eth0“在此处填写ip6addr”可能是因为您的环回接口已启用ip6支持,因此本地ping无任何问题,您可以告诉我们您的Linux发行版和内核版本? –

6

你需要指定的IPv6平(即-I eth0)中的界面:

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

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

没有这种尝试,将导致错误信息,如:

--> # 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 

一个类似的方法你必须遵循在您的客户端应用程序中。