0

I am writing a java socket program for android:

DeviceManagerWindow.java

public class DeviceManagerWindow extends Activity
{
    Thread sendMulticast;
    ...
    ...
    WifiManager wifi = (WifiManager)getSystemService( Context.WIFI_SERVICE );
    if(wifi != null)
    {
        WifiManager.MulticastLock lock = wifi.createMulticastLock("WifiDevices");
        lock.acquire();
    }
    public void searchDevice(View view)
    {
        sendMulticast = new Thread(new MultiCastThread());
        sendMulticast.start();
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        List<Future<DeviceDetails>> deviceList = new ArrayList<Future<DeviceDetails>>();

            Callable<DeviceDetails> device = new MulticastReceiver();
            Future<DeviceDetails> submit = executorService.submit(device);
            deviceList.add(submit);

        DeviceDetails[] devices = new DeviceDetails[deviceList.size()];
        int i=0;
        for(Future<DeviceDetails> future :deviceList)
        {
            try
            {
                devices[i] = future.get();
            }
            catch(Exception e)
            {
                Log.v("future Exception: ",e.toString());
            }
        }
        listAllDevices(devices);
    }
}

In the receiver class I have following code:

MultivastReceiver.java

public class MulticastReceiver implements Callable<DeviceDetails>
{
    DatagramSocket socket = null;
    DatagramPacket inPacket = null;
    public MulticastReceiver()
    {
        try
        {
            socket = new DatagramSocket(5500);
        }
        catch(Exception ioe)
        {
            System.out.println(ioe);
        }
    }
    @Override
    public DeviceDetails call() throws Exception
    {
        // TODO Auto-generated method stub
        try
        {
                byte[] inBuf = new byte[WifiConstants.DGRAM_LEN];
                //System.out.println("Listening");
                inPacket = new DatagramPacket(inBuf, inBuf.length);
                socket.receive(inPacket);

                String msg = new String(inBuf, 0, inPacket.getLength());

                Log.v("Received: ","From :" + inPacket.getAddress() + " Msg : " + msg);
                DeviceDetails device = getDeviceFromString(msg);
                return device;
        }
        catch(Exception e)
        {
            Log.v("Receiving Error: ",e.toString());
            return null;
        }
    }
    public DeviceDetails getDeviceFromString(String str)
    {
        String type;
        String IP;
            type=str.substring(0,str.indexOf('`'));
            str = str.substring(str.indexOf('`')+1);
            IP=str;
        DeviceDetails device = new DeviceDetails(type,IP);
        return device;
    }
}

Now, the above code only searches for the first packet when it receives the first packet it stops searching for the next packet. I want it to listen to the incoming packets for 30 seconds and then quit, with the all the datas that it has received. How to do that.

If I use a infinite loop then it will never return the value, because the return statement will be placed outside the loop and if I put the return statement inside the loop it will return the value and never wait for the next packet to come.

Sharda Singh
  • 727
  • 3
  • 10
  • 19
  • isnt it thread.finalize() ? – Miloš Lukačka Apr 09 '13 at 13:27
  • Please read this thread http://stackoverflow.com/questions/3194545/how-to-stop-a-java-thread-gracefully – Jabir Apr 09 '13 at 13:31
  • 1
    You're never incrementing `i` in `for(Future future :deviceList)`. You should probably do that. – ddmps Apr 09 '13 at 13:31
  • @Pescis: I dint get U... can U please post the edited code. as ur answer? – Sharda Singh Apr 09 '13 at 13:34
  • 1
    @ShardaSingh It's not a complete answer (I'm not really understanding your question), but that is a part of it. In the loop I told you about your variable `i` will always have the value 0, meaning only `devices[0]` will be filled. – ddmps Apr 09 '13 at 13:35

3 Answers3

1

There are 2 possibilities.

You can set the socket to time-out after 30 seconds. Unfortunately this will reset every time you receive a new message. So if you know that all the messages will arrive within 30 seconds, just set the time out and the socket will eventually time out after the last packet is received.

Link to socket Timeout

Second option is to use a separate TimerTask to wake up your client so that it does not get blocked in the receive indefinitely. You will need to interrupt the client thread from the timer task which should do the job.

link to timer task

In both the cases you will need to handle the appropriate exceptions to deal with time-outs.

Osama Javed
  • 1,432
  • 1
  • 16
  • 21
0

Create a "cancel" boolean property that defaults to false, and have your while loop run until the property is set to true. Then us a timer to set "cancel" to true after thirty seconds.

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
  • 1
    The `socket.receive()` method is blocking, so if no more packets are sent, it will never return. – ddmps Apr 09 '13 at 13:39
0

I have given you the code here...

It is the same problem I guess. Not marking it.!! see if U think it is fine.

Community
  • 1
  • 1
Veer Shrivastav
  • 5,434
  • 11
  • 53
  • 83