在Android中对IP列表进行ping测试

4

我正在编写一个Android应用程序。

我有一个活动负责Ping 254个IPv4地址,并在单击“自动扫描”按钮时将连接的计算机放入数据库表中(放置IP)。 //---------------------------------------------------------------------

首先,我获取本地IP(例如192.168.1.8),然后当单击按钮时,从IP提取子字符串(对于此示例为192.168.1.),然后开始从“192.168.1.1”开始并以“192.168.1.254”结束Ping所有IP。每次Ping之后,我都进行测试以了解该Ping是否成功或失败,如果成功,则将该IP放入数据库表中,最后我会在列表视图中显示已连接的IP列表。 //---------------------------------------------------------------------

问题是Ping任务需要太长时间才能完成(大约15分钟或更长时间!),这太疯狂了。我尝试使用InetAddress.isReachable(),速度很快,但它无法找到在Windows上运行的计算机,因此我改用Process和Runtime.getRuntime().exec(cmd)。

以下是Android代码:

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]+" %");
    }
}

制造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;
        }
    }

线程是实现这一目标的好方法。可以同时处理多个! - Kirk Backus
理想情况下,您应该使用线程池来处理每个ping请求,不要一次性处理所有254个请求。 - Kirk Backus
我认为我找到了一个...让我们说是"半个解决方案",它与shell中的ping命令有关。我没有加上-W1选项(所有这些浪费时间只是为了一个单词:(!!!),当我加上这个选项时,ping命令不应超过1秒(如果我们加上-W2,则为2秒...)。 - OussaMah
我在网上搜索发现,在Java中有些人使用了一个名为“fping”的命令,该命令可以接受毫秒级别的超时选项(-t)。但是,在Android(shell)中的ping命令只能接受以秒为单位的超时时间。因此,对于我的情况而言,整个操作需要花费254秒,虽然不错,但也不完美。 - OussaMah
如果你找到了解决问题的方案,请将其作为答案发布,并将其标记为已接受的答案。 - Bryan Herbst
显示剩余3条评论
1个回答

1

我在网上搜索,发现在Java中,一些人使用了一个名为"fping"的命令,它可以接受毫秒级别的超时选项(-t)。但是在Android(shell)中,ping命令只能接受以秒为单位的超时。因此,在我的情况下,整个操作应该需要254秒,不算太糟糕...但也不完美。

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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接