簡體   English   中英

快速接收UDP數據包

[英]Receive UDP packets fast

我有一個UDP偵聽器線程,該線程被循環並在接收到數據包后調用方法。 它工作得很好,只是在第一個數據包之后很快到達多個數據包時,不會調用該方法。

一次發送兩個數據包,第一個為2字節長,第二個為3字節長。 當第二個數據包到達時,大多會觸發receive()方法。

這是UDP偵聽器類:

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

    }
}

這是device.receive()方法:

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

這是Log結果的一部分:

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...

可以看出,實際上有數據包進來,只是第二個(長度:3)數據包才經常調用receive()。

“設備”是帶有receive()方法的自定義視圖。 我也嘗試使用處理程序和具有Runnable的runOnUiThread(),但結果相同。 我認為UI線程不能這么快或類似的更新。

另外,為什么在線程日志中具有實際長度而在resume()日志中具有1500字節的數據包呢? 應該是傳遞的相同數據包。

我看到這個問題有80多種觀點。 解決方案是使用處理程序將消息發送到UI,並在新數據包出現之前重新初始化data []數組和DatagramPacket。

工作代碼為:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM