因为本文是用JAVA做的测试,JAVA在这个地方有一点奇怪。接口名称与实现(即文档名称是冲突),看JDK源码:
Because this option is a hint, applications that want to
true
to disable the LoopbackMode 当MulticastSocket的loopbackMode为true时,表示禁用IP_MULTICAST_LOOP。这一点与常规思路有点不同。
引用:BTW, I think sun's naming way is ugly, about socket.setLoopbackMode at least. When I see this line, I really think it is to enable socket's
LoopbackMode if no the following comment, but actually the name of the
parameter needed by setLoopbackMode is "disable.
先上多播通信的模拟源代码,接收端的:
接收端:
在Windows平台:
分别启动服务端,客户端在同一台Windows机器上:
java -cp . com.guojje.mcast.MultiServer -l false
java -cp . com.guojje.mcast. McastClient -p 7800 –l false
发现服务端输出收到包:
receive(from /192.168.1.62:7800):hello!!
receive(from /192.168.1.62:7800):hello!!
receive(from /192.168.1.62:7800):hello!!
receive(from /192.168.1.62:7800):hello!!
说明多播通信是正常的。
下一步我们把服务端启动脚本改为
java -cp . com.guojje.mcast.MultiServer -l true
即禁用IP_MULTICAST_LOOP,发现服务端无法收到数据包。
我们再测试客户:
java -cp . com.guojje.mcast. McastClient -p 7800 –l true.
发现对于发送端来说,IP_MULTICAST_LOOP为true 或false对结果没有影响。
那么linux是否也如此呢。
我们首先清空linux的IPV6环境,查看IPV6模块是否装载:
[root@localhost ~]# lsmod | grep ipv6
ipv6 251137 18
发现存在IPV6模块,则关闭IPV6:
使用vi编辑器,打开/etc/modprobe.conf
.在文档中加入如下的两条:
alias net-pf-10 off
alias ipv6 off
重启机器。
查看多播是否启动:
[root@localhost javawork]# route -e
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.1.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
发现没有多播路由,增加多播路由:
[root@localhost javawork]# route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0
难证一下:
[root@localhost javawork]# route -e
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.1.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
224.0.0.0 * 240.0.0.0 U 0 0 0 eth0
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
[root@localhost ~]# netstat -gn
IPv6/IPv4 Group Memberships
Interface RefCnt Group
--------------- ------ ---------------------
lo 1 224.0.0.1
eth0 1 224.0.0.251
eth0 1 224.0.0.1
OK,开始测试。
分别启动服务端,客户端在同一台linux相器上:
java -cp . com.guojje.mcast.MultiServer –b 234.2.3.4
java -cp . com.guojje.mcast. McastClient -p 7800
这里要注意与Windows系统有不同,MulticastSocket Server端绑定的地址必须是多播或者不指定,否则收不到多播包。
参考我的另一篇文章:http://guojuanjun.blog.51cto.com/277646/746408
这里出现另一个奇怪的现象,对于服务端
java -cp . com.guojje.mcast.MultiServer –b 234.2.3.4 -l true / false
IP_MULTICAST_LOOP为true 或false对结果没有影响。但客户端出怪事了。
java -cp . com.guojje.mcast.McastClient -b 192.168.1.90 -l true
当IP_MULTICAST_LOOP为true,即禁用loopbackmode时,服务端无法收到多播包.
从msdn上找到这样一段话(Sun的bug database也有相应的引用):
Note The Winsock version of the IP_MULTICAST_LOOP option is semantically different than the UNIX version of the IP_MULTICAST_LOOP option:
In Winsock, the IP_MULTICAST_LOOP option applies only to the receive path.
In the UNIX version, the IP_MULTICAST_LOOP option applies to the send path.
For example, applications ON and OFF (which are easier to track than X and Y) join the same group on the same interface; application ON sets the IP_MULTICAST_LOOP option on, application OFF sets the IP_MULTICAST_LOOP option off. If ON and OFF are Winsock applications, OFF can send to ON, but ON cannot sent to OFF. In contrast, if ON and OFF are UNIX applications, ON can send to OFF, but OFF cannot send to ON.
意思是说在windows平台, IP_MULTICAST_LOOP 应用到接收路径. 是否可以理解为在接收端启用IP_MULTICAST_LOOP.
在Linux平台, IP_MULTICAST_LOOP 应用到发送路径. 是否可以理解为在发送端端启用IP_MULTICAST_LOOP 即可。.
目前来说,这样理解是通的。
以上测试是基于IPv4平台,对于IPV6又将如何呢?
首先在Windows xp上进行IPv6的配置,目前Windows上只有Link-local,分别启动服务端,客户端在同一台windows 相器上:
java -cp . com.guojje.mcast.MultiServer –b fe80::224:1dff:fe2a:689a%4 –g ff01::1
java -cp . com.guojje.mcast. McastClient –gp ff01::1 –b fe80::224:1dff:fe2a:689a%4
却发现只有发送端IP_MULTICAST_LOOP为启用时,接收端才能收到多播数据,与linux在IPv4上的表现如一辙,Windows这种IPv4与IPv6对于IP_MULTICAST_LOOP的语义出现错位,真让人大跌眼镜。太扯淡了。
添加Global地址进行测试:
D:\javawork\NIO_SSL\bin>netsh interface ipv6 add address "本地连接" 2001:3C8:1205::4
确定。
分别启动服务端,客户端在同一台windows 相器上:
java -cp . com.guojje.mcast.MultiServer –b 2001:3C8:1205::4
java -cp . com.guojje.mcast. McastClient -p 7800 –b 2001:3C8:1205::4
没有区别,和只存在link-local是一致的:只有发送端IP_MULTICAST_LOOP为启用时,接收端才能收到多播数据,看来对于IPv6, Windows已完全倒向Linux对于IP_MULTICAST_LOOP的语义。
那么对于Linux 对于IPv6,又将如何呢?先测试只有link-local地址的情况:
java -cp . com.guojje.mcast.MultiServer –p32770 –g ff01::1
java -cp . com.guojje.mcast. McastClient -gp 32770 –g ff01::1
发现与Linux pv4一样,只有发送端IP_MULTICAST_LOOP为启用时,接收端才能收到多播数据。而服务端启用与否都不重要。
在Linux上在测试link-local方式的多播时,发现端口号需要大于32770才可能通信。不知道是什么原因。(后来证明是IPv6的防火墙问题,chkconfig ip6tables off关闭即可)
至于Linux上,IPv6 Gloal地址的多播通信,我想情况一定与Windows是一致的。暂不做测试了。