Как получать широковещательные пакеты на Android

Я пытаюсь реализовать, чтобы мое приложение могло получать некоторые широковещательные сообщения. Одно устройство отправляет сообщения на адрес 192.168.2.255. Я вижу на Wireshark, что это работает. Мое приложение должно получать эти сообщения, но оно еще не работает. Это мой код:

int port = 3123;

        // Create a socket to listen on the port.
        DatagramSocket dsocket = new DatagramSocket(port);
        dsocket.setBroadcast(true);

        // Create a buffer to read datagrams into. If a
        // packet is larger than this buffer, the
        // excess will simply be discarded!
        byte[] buffer = new byte[1024];

        // Create a packet to receive data into the buffer
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // Now loop forever, waiting to receive packets and printing them.
        while (true) {
        // Wait to receive a datagram
            dsocket.receive(packet);

            // Convert the contents to a string, and display them
            String msg = new String(buffer, 0, packet.getLength());
            System.out.println(packet.getAddress().getHostName() + ": " + msg);

            // Reset the length of the packet before reusing it.
            packet.setLength(buffer.length);

            res = msg;

            Log.d("mainGate_bc", res);
        }
    } catch (Exception e) {
          System.err.println(e);
    }

Программа застряла на строке dsocket.receive(packet). Ничего не приходит в мое приложение, пока другое устройство отправляет свои пакеты.

Эти разрешения я пробовал:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

Любая идея, почему это не работает? Какие-то дополнительные разрешения? Настройки на устройстве Android?


person user3137385    schedule 23.10.2016    source источник
comment
Спасибо, но тот же результат.   -  person user3137385    schedule 23.10.2016
comment
Код когда-либо преодолевал блокирующий вызов receive()? Если нет, посмотрите здесь для периодических прерываний по блокирующему вызову.   -  person Onik    schedule 23.10.2016
comment
Это не так. Но я также не хочу прерывать прием. Я хочу получать существующие сообщения, которые, похоже, не приходят в мое приложение.   -  person user3137385    schedule 23.10.2016
comment
Попробуйте DatagramSocket dsocket = new DatagramSocket(null); dsocket.setReuseAddress(true); dsocket.setBroadcast(true); dsocket.bind(new InetSocketAddress(port));   -  person Onik    schedule 23.10.2016
comment
К сожалению, без изменений.   -  person user3137385    schedule 23.10.2016
comment
Эти отправленные пакеты никогда не достигают вашего устройства, поэтому код никогда не преодолевает блокирующий вызов receive()... Попробуйте отправлять пакеты и получать их на одном устройстве.   -  person Onik    schedule 23.10.2016


Ответы (1)


Этот вопрос дублирует этот другой вопрос. По-видимому все широковещательные пакеты отфильтровываются, если только вы не установили многоадресную блокировку.

Итак, вам нужно что-то вроде следующего кода:

WifiManager wm = null;
MulticastLock multicastLock = null;

@Override
protected void onResume() {
    super.onResume();
    if(wm == null)wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
    if(multicastLock == null){
        multicastLock = wm.createMulticastLock("stackoverflow for the win");
        multicastLock.setReferenceCounted(true);
    }
    if(multicastLock != null && !multicastLock.isHeld()) multicastLock.acquire();
}

@Override
protected void onPause() {
    super.onPause();
    if(multicastLock != null && multicastLock.isHeld()) multicastLock.release();
}


<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
person Joshua    schedule 21.04.2017