Search code examples
androidsocketsbroadcastdatagramsocket-timeout-exception

Listening datagram socket with any ip and any port number android


Hi Am sending broadcast using DatagramSocket with specific port number. Its successfully send message. But when i listening for receive message with open ip address and any port number it throwing sockettimeoutexception. But am connected with the same network.

//manifest

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

//defined port number globally

int PORT=2739;

// starting async task

new MyClientTask().execute();

///async task

public class MyClientTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... arg0) {

            new PacketSender().run();
            new PacketReceiver().run();

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);


        }

    }

This is my sending request

public class PacketSender implements Runnable {
        @Override
        public void run() {
            DatagramSocket sendSoc = null;
            try {
                sendSoc = new DatagramSocket();
                sendSoc.setBroadcast(true);
                sendSoc.setSoTimeout(5000);
                sendSoc.setReuseAddress(true);
                byte[] ip = prop.ToBuffer();
                DatagramPacket packet = new DatagramPacket(ip,
                        ip.length, getBroadcastIp(), PORT);
                Log.d("Sending", packet.getAddress().getHostAddress() + " " + packet.getPort());
                sendSoc.send(packet);
                sendSoc.close();
            } catch (IOException e) {
                Log.d("Send", "IOException");
                e.printStackTrace();
                if (sendSoc != null)
                    sendSoc.close();
            }
        }
    }

This is my listening request

public class PacketReceiver implements Runnable {
        @Override
        public void run() {
            DatagramSocket receiveSoc = null;
            try {
              //here 0 represent any port number including system reserved port number
                receiveSoc = new DatagramSocket(0, InetAddress.getByName("0.0.0.0"));  
                receiveSoc.setBroadcast(false); //also tried with true
                receiveSoc.setSoTimeout(5000);  //alse tried with removing timeout value

                int i = 0;
                while (true) {
                    Log.d("data value", " " + i);
                    i++;
                    byte buf[] = new byte[1024];
                    DatagramPacket pack = new DatagramPacket(buf, buf.length);

                    try {
                        receiveSoc.receive(pack);

                        String message = new String(pack.getData()).trim();
                        Log.i("test", message + " server ip : " + pack.getAddress().getHostAddress());

                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                }
            } catch (SocketTimeoutException e) {
                Log.d("Main", "SocketTimeoutException");
                e.printStackTrace();
                receiveSoc.close();
                new PacketReceiver().run();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.d("Response", "IOException");
                e.printStackTrace();
            }
        }
    }

//getting broadcast ip

public InetAddress getBroadcastIp() throws IOException {
        DhcpInfo dhcp = myWifiManager.getDhcpInfo();
        int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
        byte[] quads = new byte[4];
        for (int k = 0; k < 4; k++)
            quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
        return InetAddress.getByAddress(quads);
    }

It can able to receive broadcast message from all host in LAN except the hardware which i want to communicate. I can send broadcast to it.But i cant able to receive broadcast from this particular device.


Solution

  • I fixed this issue from the below. There is no problem with packet forwarding in network. I send and receive broadcast on the same socket object with setBroadcast value true. So socket send broadcast and listening for any broadcast from the same. You should not use different socket object for listening broadcast. I understand it very late.

    public class PacketSender extends Thread {
            @Override
            public void run() {
                DatagramSocket sendSoc = null;
                try {
                    sendSoc = new DatagramSocket();
                    sendSoc.setBroadcast(true);
                    InetSocketAddress  address = new InetSocketAddress(getBroadcastQuadIp(), PORT);
    
                    byte[] ip = prop.ToBuffer();
                    DatagramPacket packet = new DatagramPacket(ip,
                            ip.length, address.getAddress(), address.getPort());
    
    
                    sendSoc.send(packet);    
    
                    //////////// receiver begin
                    int i = 0;
                    while (true) {
    
                        i++;
    
                        final byte buf[] = new byte[1024];
                        final DatagramPacket pack = new DatagramPacket(buf, buf.length);
                        try {
                            sendSoc.receive(pack);
    
                            String message = new String(pack.getData()).trim();
    
                            Log.i("test", message + " server ip : " + pack.getAddress().getHostAddress());
    
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
    
                        }
                    }
                } catch (IOException e) {
                    Log.d("Send", "IOException");
                    e.printStackTrace();
                    if (sendSoc != null)
                        sendSoc.close();
                }
            }
        }