您的位置:首页 > 其它

IPv4和IPv6互操作问题

2011-10-10 19:06 141 查看
最近在给程序添加IPv6支持,因此遇到了IPv4与IPv6互操作的问题。

《UNIX网络编程》上提到,只要给Socket绑定IPv6的通配地址,就可以在双栈协议的机器上用一个IPv6套接字同时监听IPv4和IPv6端口:

struct sockaddr_in6 tempAddr;

memset(&tempAddr,0,sizeof(tempAddr));

tempAddr.sin6_port=htons(localPort);

tempAddr.sin6_family = AF_INET6;

tempAddr.sin6_addr = in6addr_any;

ret = bind(s,(sockaddr *)&tempAddr,sizeof(tempAddr));

但是我在测试的时候,却发现IPv4的客户端无法向IPv6服务端发起连接,connect返回结果是10061,即“目标机器积极拒绝”。出现这个错误表明目标机器的端口没有被监听,也就是说实际上IPv6套接字没有在监听IPv4的连接。同时,如果我把服务端和客户端都改成IPv4或者IPv6,两者能够正常通信。

这就跟书上说的不一致了,查了很多资料,发现,微软是这么说的:

“In order to support both IPv4 and IPv6 on Windows XP with Service Pack 1 (SP1) and on Windows Server 2003, an application has to create two sockets, one socket for use with IPv4 and one socket for use with IPv6. These two sockets
must be handled separately by the application.

Windows Vista and later offer the ability to create a single IPv6 socket which can handle both IPv6 and IPv4 traffic. For example, a TCP listening socket for IPv6 is created, put into dual stack mode, and bound to port 5001.
This dual-stack socket can accept connections from IPv6 TCP clients connecting to port 5001 and from IPv4 TCP clients connecting to port 5001. This feature allows for greatly simplified application design and reduces the resource overhead required of posting
operations on two separate sockets. ”

也就是说Vista以上的系统才支持IPv6 套接字同时监听IPv4和IPv6端口,并且有一个选项“IPV6_V6ONLY”,可以设置,如果IPV6_V6ONLY为非0值,则IPv6套接字只监听IPv6端口,反之,可以同时监听IPv4、IPv6端口。该选项默认是启用的,下面是关闭选项的示例代码:

int ipv6Only = 0;

ret = ACE_OS::setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(const char*)&ipv6Only,sizeof(ipv6Only));

恍然大悟,我原来测试的机器是XP,所以一直无法成功 ,接着我在XP和WIN 7上测试了下IPV6_V6ONLY选项,结果是XP上不存在IPV6_V6ONLY选项,会提示设置错误,而WIN 7上选项正常,能够同时监听IPv4和IPv6端口。

至于Linux系统,应该也支持该选项,不过没有测试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: