admin 管理员组

文章数量: 1086866

Java UDP 广播、组播使用

**知识点:**单播:与某个人聊天 多播:拉了个群进行群聊 (多播IP地址就是D类IP地址,即224.0.0.0至239.255.255.255之间的IP地址) 广播:类似微信群发 可以这么简单理解,具体大家另行了解。
**问题描述:**在笔记本电脑上跑多播服务,偶现收不到客户端发送的多播信息,关闭其中一个不用网卡重启服务就可以收到了。
**问题分析:**通过抓包,发现客户端发送的多播消息已经到了笔记本电脑上,只是多播服务没有收到。证明网络是通的,并且多播客户端已经成功发送消息。
故怀疑是多网卡问题,因为笔记本电脑当时有线网卡和无线网卡同时在运行,而多播服务默认监听其中一个网卡A,当多播客户端通过另一个网卡B发送消息时,

则多播服务无法收到消息。

  MulticastSocket ds=null;DatagramPacket packet = null;// 存储发来的消息byte[] buf = new byte[1024];try {//使用多播ds = new MulticastSocket(10007);InetAddress   receiveAddress=InetAddress.getByName("239.106.106.255");ds.joinGroup(receiveAddress);packet = new DatagramPacket(buf, buf.length);while (true) {ds.receive(packet);buf = Arrays.copyOfRange(packet.getData(), 0, packet.getLength());//消息处理// parse(packet.getAddress(), buf);}} catch (Exception e) {logger.error("寻址监听出错",e);} finally {ds.close();

查看 InetAddress.getByName(“239.106.106.255”)的源码 如下图:

可以确定原来的代码确实只监听了默认的网卡地址。
解决方案:

1、多播服务监听所在服务器(电脑)的所有有效网卡地址。

2、多播客户端发送其所有有效网卡地址。
我是做服务端的,毫无疑问选择的是方案一。
实现过程:

  public void start() throws Exception {MulticastSocket ds = null;DatagramPacket packet = null;// 存储发来的消息byte[] buf = new byte[1024];try {//使用多播ds = new MulticastSocket(10007);InetAddress  receiveAddress=InetAddress.getByName("239.106.106.255");//默认网卡监听//  ds.joinGroup(receiveAddress);//获取有效网卡地址List<NetworkInterface> addressList = NetworkUtil.getNetworkInterfaces();//端口不冲突就行int port = 10009;for (NetworkInterface networkInterface : addressList) {InetSocketAddress inetSocketAddress = new InetSocketAddress(receiveAddress, port);//将有效网卡加入组播ds.joinGroup(inetSocketAddress, networkInterface);port++;}packet = new DatagramPacket(buf, buf.length);while (true) {ds.receive(packet);buf = Arrays.copyOfRange(packet.getData(), 0, packet.getLength());//消息处理//  parse(packet.getAddress(), buf);}} catch (Exception e) {logger.error("寻址监听出错", e);} finally {ds.close();}}
public class NetworkUtil {private final static String LOCAL_IP = "127.0.0.1";/*** 获取本机有效所有网卡地址** @return  List<NetworkInterface> ip列表* @throws*/public static List<NetworkInterface> getNetworkInterfaces() throws Exception {List<NetworkInterface> localIPlist = new ArrayList<NetworkInterface>();Enumeration<NetworkInterface> interfs = NetworkInterface.getNetworkInterfaces();if (interfs == null) {return null;}while (interfs.hasMoreElements()) {NetworkInterface interf = interfs.nextElement();Enumeration<InetAddress> addres = interf.getInetAddresses();while (addres.hasMoreElements()) {InetAddress in = addres.nextElement();if (in instanceof Inet4Address) {if (!LOCAL_IP.equals(in.getHostAddress())){localIPlist.add(interf);}}}}return localIPlist;}}

**问题验证:**验证网卡是否加入多播组
windows: 执行 netsh interface ipv4 show joins
Linux: 执行 netstat -g
我的是windows,如图:可以看出有线网卡和无线网卡都加入了多播组。至此问题解决

这个解决了部分组播遇到多网卡的问题,无法进行监听。借鉴自-MK 乘风破浪~

本文标签: Java UDP 广播组播使用