简体   繁体   中英

Receive UDP packets fast

I have an UDP listener thread, which is looped and calls a method once a packet is received. It works just fine, just that the method is not being called when more than one packet arrives quickly after the first one.

Two packets are send once after another, first is 2 bytes long, the second is 3 bytes long. The receive() method tends to be fired mostly when the second packet arrives.

Here is the UDP listener class:

public class UDPListener extends Thread{
    private boolean running = true;
    byte[] data = new byte[1500];
    DatagramPacket packet = new DatagramPacket(data, data.length);

    public void run() {
        Log.v("MR", "Runs");
        try {
            while(running) {
                Log.v("MR", "Listening... ");

                socket.receive(packet);
                Log.v("MR", "Received Data: " + packet.getData()[0] + "; Length: " + packet.getLength());

                device.post(new Runnable() {
                    public void run() {
                        device.receive(packet.getData(), packet.getData().length);                           
                    }
                });

            }
        } catch (Throwable e) {
            e.printStackTrace();
            Log.v("MR", "Failed receiving");
        }

    }
}

Here is the device.receive() method:

public final void receive(byte[] inData, int length) {
    data = inData;
    dataLength = length;
    Log.v("MR", "Receive(): Data: +" + data[0] + "; Length: " + String.valueOf(data.length));
}

Here is part of the Log result:

10-18 17:24:34.393  Received Data: 79; Length: 3
10-18 17:24:34.393  Listening...
10-18 17:24:34.393  Receive(): Data: +79; Length: 1500
10-18 17:24:34.393  Receive(): Data: +79; Length: 1500
10-18 17:24:34.413  Received Data: 6; Length: 2
10-18 17:24:34.413  Listening...
10-18 17:24:34.413  Received Data: 79; Length: 3
10-18 17:24:34.413  Listening...
10-18 17:24:34.413  Receive(): Data: +79; Length: 1500
10-18 17:24:34.413  Receive(): Data: +79; Length: 1500
10-18 17:24:34.423  Received Data: 6; Length: 2
10-18 17:24:34.423  Listening...

As it can be seen packets are actually coming in, just receive() is called more often for the second (length: 3) packet.

'device' is a custom view, with receive() method. I tried also with handler and runOnUiThread() with Runnable but same results. I assume the UI thread can't be updated so fast or something similar.

Also, why are the packets with the real length in the thread log and 1500 bytes in the resume() log? It is supposed to be the same packet passed.

I saw there are 80+ views of this question. The solution was to use a handler to send a message to the UI and to re-initialize the data[] array and the DatagramPacket before a new packet comes.

The working code is:

public static class UDPListener extends Thread{
        private boolean running = true;
        Message msg;
        byte[] data;
        DatagramPacket packet;

        public void run() {
            try {
                while(running) {
                    data = new byte[1500];
                    packet = new DatagramPacket(data, data.length);

                    //Blocks and waits for a packet
                    socket.receive(packet);

                    //Send packet message to UI
                    msg = UDPReceiveHandler.obtainMessage();
                    msg.obj = packet;
                    UDPReceiveHandler.sendMessage(msg);

                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM