Отправлять широковещательный UDP, но не получать его на других устройствах Android

Я пытаюсь разработать приложение, которое отправляет некоторые широковещательные сообщения и получает ответы от других устройств Android. У меня возникают проблемы с получением сообщений UDP с других устройств. Я должен упомянуть, что этот код работал на Gingerbread, но на JellyBean он больше не работает, и я не знаю, в чем проблема.

Здесь я отправляю широковещательное сообщение (я знаю, что другие устройства прослушивают порт 5000):

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(); 

И разрешения на файл манифеста:

 <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"/> 

Я протестировал, если сообщения отправляются с помощью wireshark и tcpdump, и они отправляются. Более того, что еще более странно, я получаю широковещательные сообщения, которые я отправляю (но я их отбрасываю, потому что мне не нужно обрабатывать сообщения, отправленные от меня), но я не получаю широковещательные сообщения, отправленные с других устройств (которые должны иметь В том же формате, только исходный адрес будет отличаться и сообщение содержит, в любом случае это не должно влиять на широковещательное сообщение).

Пожалуйста, дайте мне знать, если у вас есть какие-то идеи, потому что у меня действительно закончилось все, что я мог попробовать. Любая помощь будет оценена по достоинству. Благодаря!

EDIT: Я сделал несколько тестов, и даже если я запускаю на каждом из телефонов ifconfig wlan0, и он говорит что-то вроде

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

Это означает, что интерфейс активен, а IP установлен и может принимать широковещательные сообщения и многоадресные сообщения, но когда я использую

  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); } 

Я получил эту работу, используя метод, описанный здесь, для расчета широковещательного адреса: 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); } 

Я столкнулся с вашим сообщением при попытке решить подобную проблему. Вы заработали свои вещи?

В моем случае я пытался получить Nexus 7 (первый ген с Jelly Bean 4.3) и Nexus One (Gingerbread 2.3.6), разговаривающий друг с другом через UDP. Первоначально мое приложение, работающее на обоих устройствах, успешно связывалось, но только с односторонней связью с телефона на планшет. У меня было только одно разрешение в манифесте: ИНТЕРНЕТ. Коммуникация с планшета на телефон начала работать, как только я добавил разрешение ACCESS_NETWORK_STATE для манифеста.

Поэтому по какой-то причине Nexus 7 доволен только разрешением INTERNET для отправки и приема UDP-пакетов (ну, по крайней мере, моей конкретной реализации). Nexus One отправит только с разрешения INTERNET, но не получит, если не будет предоставлено разрешение ACCESS_NETWORK_STATE.

Ваш код похож на мой (я не признаю ваши звонки «UTILS.», Однако). В моем случае, однако, для целей тестирования я жестко закодировал широковещательный адрес (192.168.n.255). Я нахожусь в точке доступа, когда вы находитесь в сети adhoc. Возможно, это тоже имеет какой-то эффект.