Android设备没有收到组播包

时间:2012-11-04 18:55:24

标签: java android networking

我正在开发一个聊天应用程序,其中Android客户端将使用多播(UDP)交换其IP。

每个设备都会在一个单独的线程中将其ip发送到多个客户端(运行此应用程序的所有设备)。将有另一个接收器线程将侦听这些多播数据包。这是我的代码。

//多播代码。

DatagramSocket socket = new DatagramSocket(9898);
            byte buff[] = ip.getBytes();
            DatagramPacket packet = new DatagramPacket(buff, buff.length, InetAddress.getByName("224.0.0.1"),9999);
            socket.send(packet);
            socket.close();

//接收者代码

MulticastSocket socket = new MulticastSocket(9999);
        InetAddress group = InetAddress.getByName("224.0.0.1");
        socket.joinGroup(group);

        DatagramPacket packet;

            byte[] buf = new byte[256];
            byte  b = 'x'; //just a separator for time being
            Arrays.fill(buf,b);
            packet = new DatagramPacket(buf, buf.length);
            String received= "";
            while(received!=null)
            {
                socket.receive(packet);
                received = new String(packet.getData());
                received = received.substring(0,received.indexOf('x'));
                this.setIp(received);
                System.out.println("Address: " + received);
            }

        socket.leaveGroup(group);
        socket.close();

问题是每个设备都打印自己的地址。它似乎永远不会收听其他多播包(我的意思是它应该打印其他的ip)。我也得到一个下面的日志,不知道这是否相关。

11-04 23:56:17.985: I/OSNetworkSystem(603): mcastAddDropMembership interfaceIndex=0

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:10)

您需要在应用中获得MulticastLock,这样您的应用才能接收未在网络上明确发送到此设备的数据包。

需要许可:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

示例代码:

// Acquire multicast lock
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();

//Do some mutlicast job here
... ...

// Once your finish using it, release multicast lock
if (multicastLock != null) {
    multicastLock.release();
    multicastLock = null;
}

答案 1 :(得分:1)

在android中实现了IPv4多播支持。还存在杯形蛋糕时代的错误。

我遇到了类似的问题,我正在做一个依赖mDNS /多播进行服务发现的项目。我的Android应用程序根本不会订阅多播组。我通过在Ubuntu 14.04计算机上创建一个便携式访问点并在其上运行tcpdump来验证这一点。连接到它的Android设备根本不会发出加入组所需的IGMP消息。我可以发送数据包但不接收它们。

我注意到每当我加入网络时,我都会向所有系统发送IPv6加入组消息。这促使我尝试使用IPv6多播地址,但这很有效。

较新的Android设备支持IPv6,它具有内置和强制多播支持。因此,不要使用Class 4 IPv4多播地址,而是修改代码以使用IPv6地址。这将使您的代码至少在本地级别上运行。

http://developer.android.com/reference/java/net/Inet6Address.html

此页面提供了大量有关根据您的需求使用哪种IP的信息。

有人说它在没有WiFiManager.crrateMulticastLock()的情况下工作,但我没有尝试过。

理论上,向全球网络多播当然是可能的。但我从来没有见过一个成功的实际实施。鉴于周围存在深奥的路由器和防火墙。

这个问题显示了它是如何在桌面上完成的。类似的代码也适用于android。

IPv6 Multicast example