简体   繁体   English

Android设备没有收到组播包

[英]Android device not receiving multicast package

I am developing a chat application where Android clients will exchange their IP's using multicasting(UDP). 我正在开发一个聊天应用程序,其中Android客户端将使用多播(UDP)交换他们的IP。

Every device will send its ip to multiple clients(all the devices running this app) in one separate Thread. 每个设备都会在一个单独的线程中将其ip发送到多个客户端(运行此应用程序的所有设备)。 There will be another receiver thread which will listen to these multicast packets. 将有另一个接收器线程将侦听这些多播数据包。 Here is my code. 这是我的代码。

//Multicasting code. //多播代码

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();

//Receiver code //接收者代码

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();

The problem is every device prints its own address. 问题是每个设备都打印自己的地址。 It seems it never listens to other multicast packages(I mean it should print other ip's as well). 它似乎永远不会收听其他多播包(我的意思是它应该打印其他的ip)。 I also get a below log, not sure if that's related. 我也得到一个下面的日志,不知道这是否相关。

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

Any help will be appreciated. 任何帮助将不胜感激。

You need acquire a MulticastLock in your app, which will allow your app receive packets that are not explicitly addressed to this device on the network. 您需要在应用程序中获取MulticastLock ,这将允许您的应用程序接收未明确发送到网络上此设备的数据包。

Permission required: 需要许可:

<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"/>

Sample code: 示例代码:

// 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;
}

IPv4 multicast support in android is poorely implemented. android中的IPv4多播支持实现得很少。 There are bugs from cupcake era still present. 还存在杯形蛋糕时代的错误。

I ran into a similar problem I was doing a project that relied on mDNS/multicast for service discovery. 我遇到了类似的问题,我正在做一个依赖于mDNS /多播进行服务发现的项目。 My Android app would simply not subscribe to the multicast group. 我的Android应用程序根本不会订阅多播组。 I verified this by creating a portable access point on a Ubuntu 14.04 machine and running tcpdump on it. 我通过在Ubuntu 14.04计算机上创建一个便携式访问点并在其上运行tcpdump来验证这一点。 Android devices connected to it simply didn't emit IGMP messages required for joining a group. 连接到它的Android设备根本不会发出加入组所需的IGMP消息。 I could send packets but not receive them. 我可以发送数据包但不接收它们。

What I noticed that I was getting an IPv6 join group message to all-systems whenever I joined the networked. 我注意到每当我加入网络时,我都会向所有系统发送IPv6加入组消息。 This prompted me to try a IPv6 multicast address and that worked. 这促使我尝试IPv6多播地址,这是有效的。

Newer android devices support IPv6, which has built-in and mandatory multicast support. 较新的Android设备支持IPv6,它具有内置和强制多播支持。 So instead of using an Class 4 IPv4 multicast address, modify your code to use an IPv6 address. 因此,不要使用Class 4 IPv4多播地址,而是修改代码以使用IPv6地址。 This will make your code to work on at least the local level. 这将使您的代码至少在本地级别上运行。

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

This page has a wealth of information about which IP to use as per your needs. 此页面提供了大量有关根据您的需求使用哪种IP的信息。

Some say that it works without the WiFiManager.crrateMulticastLock() but I didn't try that. 有人说它没有WiFiManager.crrateMulticastLock(),但我没试过。

Multicasting to global networks is certainly possible theoretically. 从理论上讲,多播到全球网络肯定是可能的。 But I've never seen a successful practical implementation of one. 但我从来没有见过一个成功的实际实施。 Given the esoteric routers and firewalls that exist all around. 鉴于周围存在深奥的路由器和防火墙。

This SO question shows how it is done on desktop. 这个问题显示了它是如何在桌面上完成的。 Similar code also works with android. 类似的代码也适用于android。

IPv6 Multicast example IPv6组播示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM