Java – Android UDP is unreliable

I have extreme UDP packet loss using Android, which makes no sense The situation is as follows:

symptom:

In most cases, I am forced to send packets 10 times to get through There will be 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 noticed is that if it is not through a router, but through another access point with no Internet connection or other clients, the performance seems to be significantly improved This is expected, but my question is why Android receivers 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, there is no problem Android also has no problem sending packets (no packets are lost) Therefore, it must be related to other Android on the receiving end

I also tried to replace the PC code with packet sender, and I got the same result The problem seems to be the Android receiver I run the same UDP code on the PC and Android

UDP sending code is simple:

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:

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,p.getLength());
                Log.d("Udp tutorial","message:" + text);
                //commandParser.parseCommand(text);
                //s.close();
            }
        } catch (SocketException e)
        {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

UDPServer. The Java class is instantiated through the main activity "oncreate()" method:

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

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

The data block (from device to server) was sent correctly, but the ACK block (from server to device) seems to be missing

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)

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

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
分享
二维码
< <上一篇
下一篇>>