Android设备没有收到组播包

Sha*_*dne 8 java networking android

我正在开发一个聊天应用程序,其中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();
Run Code Online (Sandbox Code Playgroud)

//接收者代码

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();
Run Code Online (Sandbox Code Playgroud)

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

11-04 23:56:17.985: I/OSNetworkSystem(603): mcastAddDropMembership interfaceIndex=0
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.

yor*_*rkw 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"/>
Run Code Online (Sandbox Code Playgroud)

示例代码:

// 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;
}
Run Code Online (Sandbox Code Playgroud)


aga*_*ver 6

Android 中的 IPv4 多播支持实现得很差。纸杯蛋糕时代的错误仍然存​​在。

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

我注意到,每当我加入网络时,我都会收到一条发送给所有系统的 IPv6 加入组消息。这促使我尝试 IPv6 多播地址并且成功了。

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

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

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

有人说它无需 WiFiManager.crrateMulticastLock() 即可工作,但我没有尝试。

从理论上讲,向全球网络进行多播当然是可能的。但我从未见过成功的实际实施。考虑到周围存在着深奥的路由器和防火墙。

This SO Question 显示了它是如何在桌面上完成的。类似的代码也适用于 android。

IPv6 组播示例