0

I want to connect to the server, to receive a UDP message. I think the connection is true but it won't receive a udp package to me from the server. The server sends udp messages on the network, but i can't receive one? SO it will connect to the server only why isn't it sending messages to me. I don't need to send first a message to the server.

 public class TestUdpClient implements Runnable {

    private DatagramSocket sock;
    private int port = 1200;
    private String inetAddress = "122.17.4.6";
    private SocketAddress remoteAddress;
    byte[] message = new byte[200];
    private ByteBuffer b;
    private String signature;



    public void run() {

        try {
            Log.d(TAG, "S: Connecting...");
            InetSocketAddress localSocketAddress = new InetSocketAddress(0);
            remoteAddress = new InetSocketAddress(inetAddress, port);
            sock = new DatagramSocket(localSocketAddress);
            sock.connect(remoteAddress);
           System.out.println(sock.isConnected());
            boolean running = true;
            while (running) {

                // Prepare a UDP-Packet that can contain the data we want to receive
                DatagramPacket packet = new DatagramPacket(message, message.length);
                Log.d(TAG, "S: Receiving...");

                // Receive the UDP-Packet
                sock.receive(packet);
                Log.d(TAG, "S: Received: '" + new String(packet.getData()) + "'");
                synchronized (this) {
                    wait(500);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            Log.e("connection","No connection was made");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

MainActivity

View.OnClickListener buttonConnectOnClickListener =
    new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            try {
                udpClient = new UdpClient(serverAdres,poortNummer);
            } catch (IOException e) {
                e.printStackTrace();
            }


            new Thread(new ClientSendAndListen()).start();
            buttonConnect.setEnabled(false);
        }
    };
  • Can you please share the error stacktrace? – Hitesh Gupta May 21 '19 at 09:03
  • android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513) at java.net.AbstractPlainDatagramSocketImpl.connect(AbstractPlainDatagramSocketImpl.java:132) at java.net.DatagramSocket.connectInternal(DatagramSocket.java:169) at java.net.DatagramSocket.connect(DatagramSocket.java:517) at com.ict.barcodescanner.UdpClient.(UdpClient.java:31) at com.ict.barcodescanner.MainActivity$1.onClick(MainActivity.java:48) – user3761485 May 21 '19 at 09:06
  • Network operations on main thread are not allowed in Android. Create an AsyncTask and call `udpClient = new UdpClient(serverAdres,poortNummer);` from`doInBackground()` (see also here https://stackoverflow.com/a/19541474/5312102) – atarasenko May 21 '19 at 09:13
  • UDP is connectionless, calling `sock.connect()` merely filters out inbound packets so only those received from a specific peer IP/Port are returned to you. But to actually inform the server that you are ready to receive, you usually have to send a packet to the server first so it knows you even exist, unless the server is sending broadcast packets to the whole network subnet. That being said, have you sniffed the network with a packet sniffer like Wireshark to make sure the server is actually sending non-blank packets to begin with? – Remy Lebeau May 21 '19 at 20:22
  • Also, why is your thread creating a new `DatagramSocket` and `DatagramPacket` on each loop iteration? It should be creating the `DatagramSocket` and `DatagramPacket` one time before entering the loop. The loop should simply be calling `sock.receive()` (and ignoring `SocketTimeoutException` errors) until the app is ready to terminate the thread. – Remy Lebeau May 21 '19 at 20:29
  • the server is sending broadcast packets to the whole network subnet. Should i remove the sock.connect and replace with? – user3761485 May 22 '19 at 13:39

2 Answers2

0

Android sdk does not allow network requests in main thread. You must create a new thread to make network requests. You can implement the AsyncTask provided by android sdk for simplicity.

https://developer.android.com/training/articles/perf-anr

https://developer.android.com/reference/android/os/AsyncTask

Hitesh Gupta
  • 1,091
  • 9
  • 14
0

Official Android documentation

AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.)

Make your own thread instead and put all you "network related" logic/code there.

    Thread thread = new Thread(){
        void run(){
           //put all your "network related code here"
        }
    }
    thread.start();

Also server code would be helpful to understand the problem.

Community
  • 1
  • 1
Mehul Pamale
  • 349
  • 3
  • 13
  • 1
    @Mehul Can you please share an official documentation link for the fact that you have mentioned? I'm wondering because I have used AsyncTask a lot for network communications without a problem. I know that requests are executed sequentially until we provide an external executor but still the doInBackground() executes in a background thread otherwise it would freeze the UI. – Hitesh Gupta May 21 '19 at 14:26
  • My understanding is that AsyncTask is just an helper class/ wrapper class on top of the Thread class to simplify the synchronization between the background thread and main thread, because at the end we need to update the UI element after the thread completes and android also does not allow to update UI elements from threads other than the main thread to prevent accidental memory leaks. – Hitesh Gupta May 21 '19 at 14:39
  • @Hitesh Gupta I have edited the answer and added the docs in quote. Yes. My intuition is this because I was working on a project where I used to receive datagram packets in an AsyncTask which sometimes resulted in freezing the UI. – Mehul Pamale May 28 '19 at 12:17