3

我使用 MulticastSocket 在启用 Android 的开发板(4.3 版)上有一个工作的多播接收器;我想要的是能够使用 NIO 通道。由于 Android 中不存在 MulticastChannel,我尝试使用 DatagramChannel 代替它,但到目前为止没有任何运气。如果有人有任何关于将频道配置为仅进行多播接收的信息,那就太棒了!
下面是一些不起作用的示例代码,但可以大致了解我如何进行设置:

InetAddress groupAddr = InetAddress.getByName(groupAddress);
SelectorProvider 提供者 = SelectorProvider.provider();
选择器选择器 = provider.openSelector();    
DatagramChannel dc = DatagramChannel.open();
// 这个转换失败
MulticastSocket socket = (MulticastSocket) dc.socket();
//设置ttl
socket.setTimeToLive(16);
// 设置接收缓冲区
socket.setReceiveBufferSize(65536);
socket.setReuseAddress(true);
// 加入群
socket.joinGroup(groupAddr);

产生这个(我有点期待):

11-14 18:11:56.203:E/AndroidRuntime(22315):致命异常:DatagramListener
11-14 18:11:56.203: E/AndroidRuntime(22315): java.lang.ClassCastException: java.nio.DatagramChannelImpl$DatagramSocketAdapter 不能转换为 java.net.MulticastSocket
4

2 回答 2

2

工作代码。_pairChannelAndSocket() 方法

public class Sample
{
    private DatagramChannel createChannel(NetworkInterface networkIf, InetSocketAddress address)
            throws IOException {

        MulticastSocket socket = new MulticastSocket(address.getPort());
        socket.setReuseAddress(true);
        socket.setBroadcast(true);
        socket.joinGroup(MCAST_ADDRESS, networkIf);

        DatagramChannel channel = DatagramChannel.open();
        _pairChannelAndSocket(channel, socket);
        channel.configureBlocking(false);
        return channel;
    }

    public static void _pairChannelAndSocket(DatagramChannel channel, MulticastSocket socket) {
        try {
            Field f = channel.getClass().getDeclaredField("socket");
            f.setAccessible(true);
            f.set(channel, socket);
        } catch (Exception e) {
            Log.e(LOG_TAG, e.getMessage(), e);
        }
    }
}
于 2015-12-02T19:18:20.637 回答
1

我还没有尝试过,但这里有一些关于使用反射的想法:

  • 您的 DatagramChannel.socket() 返回java.nio.DatagramChannelImpl$DatagramSocketAdapter
  • 如果您检查源 - 该类DatagramSocket通过包装实际DatagramChannelImpl
  • 使用反射,您可以获得该channelImpl适配器对象的属性,这是实际的DatagramChannelImpl
  • 拥有DatagramChannelImpl实例,您可以加入/离开多播组

或者,也许尝试使用DatagramSocket.setDatagramSocketImplFactory配置多播的方式分配您的自定义工厂生产套接字实现。或者生成在其适配器中公开实际“Impl”对象的套接字实现。

于 2014-10-07T13:10:59.627 回答