Java – Android UDP is unreliable

I have extreme UDP packet loss using Android, which makes no sense. The situation is as follows: @ h_ 419_ 1@

@H_ 419_ 1@

Symptoms: @ h_ 419_ 1@

@H_ 419_ 1@

In most cases, I am forced to send packets 10 times to get through. There are some delays at other times. Very strange behavior only occurs at the receiving end of Android. If I replace android with a PC running the same code on Java or just receive packets through the UDP server of packet sender, I have no loss problem. Another thing I notice is, If not through the router, but through another access point without Internet connection or other client performance, it seems to improve significantly. This is expected, but my question is why the receiving end of Android will see such poor performance and lose so many packets. When Android is replaced by another PC running the same code and on the same network, No problem. Android has no problem sending packets (no packet loss). Therefore, it must be related to other Android at the receiving end... @ h_ 419_ 1@

I also tried to replace the PC code with packet sender, and I got the same result. The problem seems to be the receiving end of Android. I run the same UDP code on the PC and Android. @ h_ 419_ 1@

UDP sending code is very simple: @ h_ 419_ 1@

@H_ 419_ 1@

public void sendMessage(String message)
{
    try {
        DatagramSocket ds = new DatagramSocket();
        DatagramPacket dp;
        InetAddress local = InetAddress.getByName(ipPool);
        dp = new DatagramPacket(message.getBytes(), message.length(), local, port);
        ds.setBroadcast(true);
        ds.send(dp);
        ds.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

The UDP receiving code on Android is located in the UDP server class: @ h_ 419_ 1@

@H_ 419_ 1@

public class UDP_Server
{
    CommandParser commandParser;

    public UDP_Server(MainActivity mainActivity)
    {
        Log.i("Udp tutorial", "---------------------------Starting UDP SERVER");

        commandParser = new CommandParser(mainActivity);
        String text;
        int server_port = 9876;
        try
        {
            DatagramSocket s = new DatagramSocket(server_port);
            s.setBroadcast(true);
            //s.setReceiveBufferSize(163840);


            while (true)
            {
                byte[] message = new byte[1024];
                DatagramPacket p = new DatagramPacket(message, message.length);

                s.receive(p);
                text = new String(message, 0, p.getLength());
                Log.d("Udp tutorial","message:" + text);
                //commandParser.parseCommand(text);
                //s.close();
            }
        } catch (SocketException e)
        {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

Udpserver.java class is instantiated through the main activity "oncreate()" method: @ h_ 419_ 1@

@H_ 419_ 1@

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        wm = (WifiManager) getSystemService(WIFI_SERVICE);

        Log.i("Udp tutorial", "---------------------------HERE 1");
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                UDP_Server svr = new UDP_Server(MainActivity.this);
            }
        });

        thread.setPriority(Thread.MAX_PRIORITY);
        thread.start();
//        TCPServer server = new TCPServer();
    }

Solution: @ h_ 419_ 1@

I have some disastrous results. Some Android devices send files to TFTP (UDP based) servers over WiFi, but it seems to work well with other Android devices. @ h_ 419_ 1@

The data block (from device to server) was sent correctly, but the ACK block (from server to device) seems to be missing. @ h_ 419_ 1@

It turns out that I have to get a multicast lock to make these faulty devices work properly (credit to https://www.b4x.com/android/forum/threads/enable-multicast.43321/#post -263242)@H_ 419_ 1@

@H_ 419_ 1@

WifiManager wifi = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();

...

multicastLock.release();

I hope this will help. @ h_ 419_ 1@

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>