Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android系統教程 >> Android開發教程 >> Android上UDP組播無法接收數據的有關問題

Android上UDP組播無法接收數據的有關問題

編輯:Android開發教程

Android上UDP組播無法接收數據的問題

  最近,想做一個跨平台的局域網的文件傳輸軟件,思路是組播設備信息,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             @Override
31             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     @Override
17     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"));

  

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved