最近,想做一个跨平台的局域网的文件传输软件,思路是组播设备信息,TCP连接传输文件。于是进行了一次简单的UDP组播测试,发现Android对于UDP组播接收数据的支持即极为有限。

部分代码如下

 1 package com.hsocket.Udp; 2  3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6  7 public class UdpReceiver { 8     protected DatagramSocket client=null; 9     private OnReceiveListener mOnReceiveListener=null;10     private Thread thrRecv=null;11     protected int port=0;12     public UdpReceiver(int port){13         this.port=port;14     }15     protected DatagramSocket Create() throws IOException{16         return new DatagramSocket(this.port);17     }18     public void addOnReceiveListener(OnReceiveListener mOnReceiveListener){19         this.mOnReceiveListener=mOnReceiveListener;20     }21     public void Stop(){22         if(this.thrRecv!=null) this.thrRecv.interrupt();23         this.Close();24     }25     public void Listen() throws IOException{26         this.Close();27         this.client=this.Create();28         if(this.thrRecv!=null) this.thrRecv.interrupt();29         this.thrRecv=new Thread(new Runnable() {30             @Override31             public void run() {32                 while(!Thread.interrupted()){33                     ReceiveEventArgs args=new ReceiveEventArgs();34                     try {35                         DatagramPacket packet=UdpReceiver.this.Receive();36                         args.Address=packet.getAddress();37                         args.Result=packet.getData();38                         args.Length=packet.getLength();39                         args.Error=false;40                     } catch (IOException e) {41                         e.printStackTrace();42                         args.Exception=e;43                         args.Error=true;44                     }45                     UdpReceiver.this.OnReceive(args);46                     if(UdpReceiver.this.mOnReceiveListener!=null)47                         UdpReceiver.this.mOnReceiveListener.OnReceive(UdpReceiver.this, args);48                 }49             }50         });51         this.thrRecv.start();52     }53     protected DatagramPacket Receive() throws IOException{54         byte[] recvBuf = new byte[4096];55         DatagramPacket recvPacket= new DatagramPacket(recvBuf , recvBuf.length);56         this.client.receive(recvPacket);57         return recvPacket;58     }59     protected void Close(){60         if(this.client!=null) this.client.close();61     }62     protected void OnReceive(ReceiveEventArgs args){63         64     }65 }
View Code
 1 package com.hsocket.Udp; 2  3 import java.io.IOException; 4 import java.net.DatagramSocket; 5 import java.net.InetAddress; 6 import java.net.MulticastSocket; 7  8 public class UdpMultcastReceiver extends UdpReceiver { 9 10     private InetAddress multicastAddr=null;11     public UdpMultcastReceiver(InetAddress multicastAddr,int port) {12         super(port);13         this.multicastAddr=multicastAddr;14     }15 16     @Override17     protected DatagramSocket Create() throws IOException {18         MulticastSocket socket=new MulticastSocket(this.port);19         socket.joinGroup(this.multicastAddr);20         socket.setLoopbackMode(false);21         return socket;22     }23 }
View Code

  发现UDP组播接收数据在部分机型存在问题,与系统有极大关系。小米、华为的手机的深度定制系统对UDP的封杀极为严重。

  首先是组播锁,Android的Wifi,默认情况下是不接受组播的,详见:http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html

要想打开组播功能,有以下几个步骤:

  • 在Manifest文件中加入:android.permission.CHANGE_WIFI_MULTICAST_STATE,这个权限
  • 获取到MulticastLock对象,这个对象不能直接实例化,要通过WifiManager间接得到,工厂模式
  • 调用MulticastLock对象的acquire方法,获取到组播锁
  • 相应的,用完组播,为了不浪费电力,要调用MulticastLock的release方法释放锁
WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE);         multicastLock=wifiManager.createMulticastLock("multicast.test");         multicastLock.acquire(); 

  其次,即使获取到组播锁,但部分机型依旧无法接收到广播,因为部分Android手机有多网卡,默认是本地回环网卡,IP为127.0.0.1,无法加入组播,需用MulticastSocket::setNetworkInterface来设置组播网卡

mMulticastSocket.setNetworkInterface(NetworkInterface.getByName("wlan0"));

  

 

转载于:https://www.cnblogs.com/Ralap/p/Android_udp_multcast_solution.html

更多相关文章

  1. 简单模拟Android中AlertDialog的Builder设计模式
  2. android获取网络图片
  3. Python 通过脚本获取Android的apk的部分属性,再通过加密算法生成
  4. Android:Activity(三):启动其他Activity并返回结果
  5. Android根据所设置的textSize获取字体高度和设置行高
  6. Android之判断是否安装某个应用
  7. Android稳定性问题分析时获取手机状态的ADB命令
  8. Android获取目录
  9. Java入侵检测(三)

随机推荐

  1. Android 发送JSON数据到服务端
  2. 关于做Android+J2ee系统集成开发的一点心
  3. Android 05:点击事件的四种写法
  4. Android 将数据库文件保存至sdcard中
  5. Android(安卓)Socket 通信实例...【Pnoke
  6. 日常get知识记录【7】Android 错误:This p
  7. 读取 android /system/build.prop 的最简
  8. Android中AVD的使用以及错误处理方法
  9. Android知识
  10. Android Recovery 升级方法