2013-06-25 14 views
11

ブロードキャストメッセージを送信し、他のアンドロイドデバイスから回答を受け取るアプリを開発しようとしています。私は、他のデバイスからUDPメッセージを受信するのにいくつかの問題があります。私はこのコードがGingerbreadで動作することを言及する必要がありますが、JellyBeanではもう動作しません。何が問題か分かりません。私は(私は他のデバイスがポート5000でリッスン知っている)ブロードキャストメッセージを送るのはここブロードキャストUDPを送信しますが、他のAndroidデバイスでは受信しません。

は次のとおりです。私はそれを受け取る場所

private void sendUDPMessage(String msg) { 

    try { 
     DatagramSocket clientSocket = new DatagramSocket(); 

     clientSocket.setBroadcast(true); 
     InetAddress address = InetAddress.getByName(Utils.getBroadcastAddress()); 

     byte[] sendData; 

     sendData = msg.getBytes(); 
     DatagramPacket sendPacket = new DatagramPacket(sendData, 
       sendData.length, address, 5000); 
     clientSocket.send(sendPacket); 

     clientSocket.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

そして、ここでは、次のとおりです。

private void start_UDP() 
{ 
    try { 
      serverSocketUDP = new DatagramSocket(5000); 
     } 
    catch (Exception e) { 

     Log.i(LOGTAG, "Exception opening DatagramSocket UDP"); 
    } 

    final byte[] receiveData = new byte[1024]; 


    while(runningUDP) { 
     Log.d(LOGTAG, "Waiting for Broadcast request in ServerUDP."); 

     final DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 

     serverSocketUDP.receive(receivePacket); 


       byte[] sendData = new byte[1024]; 
       InetAddress address = receivePacket.getAddress(); 
       int port = receivePacket.getPort(); 
       if(!receivePacket.getAddress().getHostAddress().equals(Utils.getLocalIpAddress())) 
       { 
        String req = new String(receivePacket.getData(), 0, receivePacket.getLength()); 


        Log.d(LOGTAG, "Received UDP message : "+req+" from: "+receivePacket.getAddress().getHostAddress()); 
       } 
         }// while ends 
     }//method ends 

私はそれを言及する必要がありますこれらの2つの関数は2つの異なるスレッドで分離されているので、私は同時に送受信できます。

私はまた、次のロック獲得:

powerManager =(PowerManager)context.getSystemService(Context.POWER_SERVICE); 
    wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK ,LOGTAG); // PARTIAL_WAKE_LOCK Only keeps CPU on 
    wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
    wifiLock = wifiManager.createWifiLock(3, LOGTAG); 
    multicastLock = wifiManager.createMulticastLock(LOGTAG); 

    wakeLock.acquire(); 
    multicastLock.acquire(); 
    wifiLock.acquire(); 

とマニフェストファイルのパーミッション:メッセージはWiresharkのとtcpdumpのを使用して送信され、それらが送信された場合、私はテストしている

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<uses-permission android:name="android.permission.WRITE_SETTINGS"/> 
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/> 

を。さらに、奇妙なことに、私は自分が送信したブロードキャストメッセージを受信します(しかし、私は自分自身から送られたメッセージを処理する必要はないのでそれらを破棄します)。しかし、他のデバイスから送信されたブロードキャストメッセージは受信しません同じフォーマットでは、送信元アドレスだけが異なり、メッセージが含まれています。いずれの方法でもブロードキャストメッセージに影響を与えてはいけません)。

私が試してみることのできるものが本当になくなったため、アイデアがあれば教えてください。どんな助けもありがとう。ありがとう!

編集:私は、いくつかのテストを行った 場合でも、私は電話のifconfig wlan0の各上で実行され、それが言うとき、インターフェイスがアクティブで、IPが設定されていることを意味

ifconfig wlan0 
    wlan0: ip 169.254.17.28 mask 255.255.0.0 flags [up broadcast multicast] 

のようなものとブロードキャストメッセージとマルチキャストメッセージを受信できますが、使用するときは

    InetAddress in=InetAddress.getByName("169.254.17.28"); 
      if (in.isReachable(1000)) 
       Log.i(LOGTAG, "host is reachable"); 
      else 
       Log.i(LOGTAG, "host is not reachable"); 

これはログに表示されるホストに到達できません。

私は同様の問題を解決しようとすると、私はあなたのポストに出くわしたのWi-Fiの上

private void startWifiAdhoc() { 

    WifiManager wifiManager =  (WifiManager)SharingFileService.context.getSystemService(Context.WIFI_SERVICE); 
    String command=""; 
    if (condWifiAdhoc == false) { 

     condWifiAdhoc=true; 
     wifiInterface = Utils.getWifiInterface(); 


     wifiManager.setWifiEnabled(true); 
     localIP = Utils.getLinkLocalAddress(); 
    } 
    else 
    { 
     wifiManager.setWifiEnabled(true); 
     localIP = Utils.getLinkLocalAddress(); 
    } 
     // Set wifi ad-hoc 
     command = context.getFilesDir().getPath() 
       + "/iwconfig " + wifiInterface + " mode ad-hoc essid " 
       + "mcp" + " channel " + "1" + " commit\n"; 

     Log.i(LOGTAG, command); 
     Utils.rootExec(command); 


     Log.i(LOGTAG, "Ip address used :" + localIP); 
     command = context.getFilesDir().getPath() 
       + "/ifconfig " + wifiInterface + " " + localIP 
       + " netmask 255.255.0.0 up\n"; 



     Log.i(LOGTAG, command); 
     Utils.rootExec(command); 

} 
+0

注意は、いくつかのことルータはデフォルトでマルチキャストDNSを無効にします。 – yorkw

+0

ああ...私はWi-Fiアドホックであることを言及しなければならない – Lara

+0

この投稿を見ることができます:http://stackoverflow.com/a/16208617/1028256それは、一部のwifiドライバがブロードキャストレシーバを無効にすることができ、その場合はスリープモードから復帰した後に発生します。 – Mixaz

答えて

1

を回すところです。あなたはあなたのものを働かせましたか?

私のケースでは、Nexus 7(Jelly Bean 4.3の最初の世代)とNexus One(Gingerbread 2.3.6)をUDPで話すようにしていました。最初は、両方のデバイスで動作している私のアプリは、電話からタブレットへの片方向の通信だけでリンクアップすることができました。マニフェストには、インターネットの許可が1つしかありませんでした。マニフェストにACCESS_NETWORK_STATE権限を追加したら、タブレットから電話機への通信が開始されました。

何らかの理由で、Nexus 7は、UDPパケットの送受信(少なくとも私の具体的な実装)のためのインターネットアクセス許可に満足しています。Nexus Oneはインターネットアクセスのみで送信されますが、ACCESS_NETWORK_STATEアクセス許可が与えられていないと受信しません。

あなたのコードは私のものと似ています(私はあなたの "UTILS。"呼び出しを認識しません)。私の場合は、テスト目的でブロードキャストアドレス(192.168.n.255)をハードコードしました。あなたがアドホックネットワークにいる間、私はアクセスポイントにいます。多分それにもいくつかの効果があります。

12

私はブロードキャストアドレスを計算するために、ここで説明する方法を使用してこの作業ました:https://code.google.com/p/boxeeremote/wiki/AndroidUDP

はここに私の受信機です:

try { 
    //Keep a socket open to listen to all the UDP trafic that is destined for this port 
    socket = new DatagramSocket(Constants.PORT, InetAddress.getByName("0.0.0.0")); 
    socket.setBroadcast(true); 

    while (true) { 
    Log.i(TAG,"Ready to receive broadcast packets!"); 

    //Receive a packet 
    byte[] recvBuf = new byte[15000]; 
    DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length); 
    socket.receive(packet); 

    //Packet received 
    Log.i(TAG, "Packet received from: " + packet.getAddress().getHostAddress()); 
    String data = new String(packet.getData()).trim(); 
    Log.i(TAG, "Packet received; data: " + data); 

    // Send the packet data back to the UI thread 
    Intent localIntent = new Intent(Constants.BROADCAST_ACTION) 
      // Puts the data into the Intent 
      .putExtra(Constants.EXTENDED_DATA_STATUS, data); 
    // Broadcasts the Intent to receivers in this app. 
    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); 
    } 
} catch (IOException ex) { 
    Log.i(TAG, "Oops" + ex.getMessage()); 
} 

そして、ここでは私の送信者:

public void sendBroadcast(String messageStr) { 
    // Hack Prevent crash (sending should be done using an async task) 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 

    try { 
     //Open a random port to send the package 
     DatagramSocket socket = new DatagramSocket(); 
     socket.setBroadcast(true); 
     byte[] sendData = messageStr.getBytes(); 
     DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, getBroadcastAddress(), Constants.PORT); 
     socket.send(sendPacket); 
     System.out.println(getClass().getName() + "Broadcast packet sent to: " + getBroadcastAddress().getHostAddress()); 
    } catch (IOException e) { 
     Log.e(TAG, "IOException: " + e.getMessage()); 
    } 
    } 

    InetAddress getBroadcastAddress() throws IOException { 
    WifiManager wifi = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 
    DhcpInfo dhcp = wifi.getDhcpInfo(); 
    // handle null somehow 

    int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask; 
    byte[] quads = new byte[4]; 
    for (int k = 0; k < 4; k++) 
     quads[k] = (byte) ((broadcast >> k * 8) & 0xFF); 
    return InetAddress.getByAddress(quads); 
    } 
+0

このコードは、デバイスが同じローカルネットワーク上にある場合にのみ機能しますか? – zer0uno

+0

はい、正しくは – caspii

+0

がAndroid 5.1.1とAndroid 7.1.2で確認されています –

関連する問題