4

I'm programming an android APP.

I have an activity responsable on Pinging 254 IPv4 and Putting the connected machines in a Database Table ( putting the ip )when a Button "Auto Scan" is clicked. //---------------------------------------------------------------------

First i get the Local IP ( for exemple 192.168.1.8), then when the button clicked, i extract a subString from the ip ( 192.168.1. for this exemple) then start pinging all the IPs starting from "192.168.1.1" and finishing with "192.168.1.254". after every ping, i make a test to know if that ping succeeded or failed, if it succeeded then i put that ip in a database table, then finally i show the list of connected IPs in a listview. //---------------------------------------------------------------------

The problem is that the Pinging task is taking too long to finish ( about 15min or more !!), it's crazy. I tried to use InetAddress.isReachable() it was fast, but it can't find a computer working with windows, so i changed to work with Process & Runtime.getRuntime().exec(cmd).

Below the android code :

class MyTask extends AsyncTask<String, Integer, Void> {         

    Dialog dialog;
    ProgressBar progressBar;
    TextView tvLoading,tvPer;
    Button btnCancel;

    @Override
    protected Void doInBackground(String... params) {
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);

        String s="", address = params[0];
        int index=0,j=0,count=0;

        //on prend le dernier index du char "."
        final StringBuilder ss = new StringBuilder(address);
        index = ss.lastIndexOf(".");
        //on prend une souschaîne qui contient l'ipv4 sans le dernier nombre
        s = address.substring(0,index+1);

        //Tester tous les adresses Ipv4 du même plage d'adresses
        for(int i=1; i<255; i++){
            if (isCancelled()) {
                break;
            }
            if(testping(s+""+i+"")){
                insertIPv4(s+""+i+"");}
            count++;
            if(count == 5 && j<100){
                count=0;
                j+=2;
                publishProgress(j);
            }
        }
        return null;
    }

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

        dialog.dismiss();

        AlertDialog alert = new AlertDialog.Builder(Gestion_Machines.this)
                .create();

        alert.setTitle("Terminé");
        alert.setMessage("Operation Terminé avec Succés");
        alert.setButton("OK", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        alert.show();
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dialog = new Dialog(Gestion_Machines.this);
        dialog.setCancelable(false);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.progressdialog);

        progressBar = (ProgressBar) dialog.findViewById(R.id.progressBar1);
        tvLoading = (TextView) dialog.findViewById(R.id.tv1);
        tvPer = (TextView) dialog.findViewById(R.id.tvper);
        btnCancel = (Button) dialog.findViewById(R.id.btncancel);

        btnCancel.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                objMyTask.cancel(true);
                dialog.dismiss();
            }
        });

        dialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        progressBar.setProgress(values[0]);
        tvLoading.setText("Loading...  " + values[0] + " %");
        tvPer.setText(values[0]+" %");
    }
}

and The Method that make the ping :

public boolean testping(String x){
        int exit=22;
        Process p;

        try {
            //.....edited line.....
             p = Runtime.getRuntime().exec("ping -c1 -W1 "+x);
            //make shure that is -W not -w it's not he same.
             p.waitFor();
            exit = p.exitValue();
            p.destroy();
        } catch (IOException ee) {
            ee.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (exit == 0) {
            return true;
        }else{
            return false;
        }
    }
parsley72
  • 8,449
  • 8
  • 65
  • 98
OussaMah
  • 817
  • 9
  • 19
  • Threads are a great way to accomplish that. Do multiple at once! – Kirk Backus Sep 03 '13 at 21:18
  • Ideally, you would use a thread pool to handle each of the ping requests, don't do all 254 at once. – Kirk Backus Sep 03 '13 at 21:27
  • It is worth being aware that runtime.exec() has some issues with how it runs. See this answer for an Andorid bug which will cause it to lock sometimes: http://stackoverflow.com/a/11411709/334402. And this link gives some background on common issues: http://www.javaworld.com/jw-12-2000/jw-1229-traps.html. – Mick Sep 03 '13 at 21:32
  • @Kirk Backus : did i have to replace Asynctask with Threads ?? i read a little about threads, but seems not a solution for my problem. – OussaMah Sep 04 '13 at 02:31
  • @Mick : thank you, but didn't find a solution to my problem, because my code is correct and my Runtime process is simple, and it works fine but the problem is about the time that takes the ping command. – OussaMah Sep 04 '13 at 02:38
  • i think i found a ..., let's say .. "Half solution", it is all about the ping command from shell. i haven't put the option -W1 (! all this lost time for a word :( !!!), when i put this option the command ping should not exceed 1 second ( 2 seconds if we put -W2 ...). – OussaMah Sep 04 '13 at 02:44
  • I searched on the net, i founf that in java, some have used a command called " fping " that accept timeout option ( -t) with milliseconds. but the ping command in android ( shell ) can only accept timeout with seconds. so, for my case, the hole operation should take 254 seconds, not bad .... but not perfect – OussaMah Sep 04 '13 at 02:46
  • If you have found a solution to your problem, please post it as an answer and mark it as the accepted answer. – Bryan Herbst Oct 04 '13 at 20:07

1 Answers1

1

I searched on the net, i founf that in java, some have used a command called " fping " that accept timeout option ( -t) with milliseconds. but the ping command in android ( shell ) can only accept timeout with seconds. so, for my case, the hole operation should take 254 seconds, not bad .... but not perfect.

public boolean testping(String x){
    int exit=22;
    Process p;

    try {
        //.....edited line.....
         p = Runtime.getRuntime().exec("ping -c1 -W1 "+x);
        //make shure that is -W not -w it's not he same.
         p.waitFor();
        exit = p.exitValue();
        p.destroy();
    } catch (IOException ee) {
        ee.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if (exit == 0) {
        return true;
    }else{
        return false;
    }
}
OussaMah
  • 817
  • 9
  • 19