【问题标题】:Pinging a list of IPs in Android在 Android 中 Ping 一个 IP 列表
【发布时间】:2013-09-03 21:09:19
【问题描述】:

我正在编写一个安卓APP。

当单击“自动扫描”按钮时,我有一项活动负责 Pinging 254 IPv4 并将连接的机器放入数据库表中(放置 ip)。 //------------------------------------------------ ---------------------

首先我获取本地 IP(例如 192.168.1.8),然后当单击按钮时,我从 ip 中提取一个子字符串(例如 192.168.1.),然后开始 ping 从“192.168.1”开始的所有 IP。 1.1”并以“192.168.1.254”结尾。在每次 ping 之后,我都会进行测试以了解该 ping 是成功还是失败,如果成功,那么我将该 ip 放入数据库表中,最后我在列表视图中显示连接的 IP 列表。 //------------------------------------------------ ---------------------

问题是 Pinging 任务需要很长时间才能完成(大约 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;
        }
    }

【问题讨论】:

  • 线程是实现这一目标的好方法。一次做多个!
  • 理想情况下,您应该使用线程池来处理每个 ping 请求,不要一次完成所有 254 个。
  • 值得注意的是,runtime.exec() 的运行方式存在一些问题。请参阅此答案以了解有时会导致其锁定的 Andorid 错误:stackoverflow.com/a/11411709/334402。此链接提供了一些常见问题的背景信息:javaworld.com/jw-12-2000/jw-1229-traps.html.
  • @Kirk Ba​​ckus:我必须用线程替换 Asynctask 吗?我读了一些关于线程的文章,但似乎不是我的问题的解决方案。
  • @Mick :谢谢,但没有找到解决我的问题的方法,因为我的代码是正确的,我的运行时过程很简单,而且运行良好,但问题在于所花费的时间ping 命令。

标签: android ping


【解决方案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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多