Ping命令不适用于Java类

时间:2019-06-12 14:01:11

标签: android ping execute traceroute

我有一个名为TracerouteWithPing的类,我正在使用它来实现traceroute实用性,因为android没有安装traceroute。当我调试类时,我注意到在执行ping命令ping -c 1 -t 1 + url时,该命令未返回任何内容。所以我决定放到我的android终端并在那里做,得到相同的结果。为什么实现ping -c 1 -t 1 url不起作用? -t 1选项用于ttl,在到达该跃点/路由器后,实现将增加一。我在github上的开源项目中找到了该类。

package org.techgeorge.traceroute.traceroute;


import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import org.techgeorge.traceroute.MainActivity;
import org.techgeorge.traceroute.R;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;



public class TracerouteWithPing {

    private static final String PING = "PING";
    private static final String FROM_PING = "From";
    private static final String SMALL_FROM_PING = "from";
    private static final String PARENTHESE_OPEN_PING = "(";
    private static final String PARENTHESE_CLOSE_PING = ")";
    private static final String TIME_PING = "time=";
    private static final String EXCEED_PING = "exceed";
    private static final String UNREACHABLE_PING = "100%";

    private TracerouteContainer latestTrace;
    private int ttl;
    private int finishedTasks;
    private String urlToPing;
    private String ipToPing;
    private float elapsedTime;
    public Context context;
    private View view ;

    // timeout handling
    private static final int TIMEOUT = 30000;
    private Handler handlerTimeout;
    private static Runnable runnableTimeout;
    ConnectivityManager connectivityManager;
    private ExecutePingAsyncTask task;

    public TracerouteWithPing(Context context) {
        this.context = context;
    }


    /**
     * Launches the Traceroute
     * 
     * @param url
     *            The url to trace
     * @param maxTtl
     *            The max time to live to set (ping param)
     */
    public void executeTraceroute(String url, int maxTtl) {
        this.ttl = 1;
        this.finishedTasks = 0;
        this.urlToPing = url;
        Log.v("trace", "trace doinbackground started");
        new ExecutePingAsyncTask(maxTtl).execute();
    }

    /**
     * Allows to timeout the ping if TIMEOUT exceeds. (-w and -W are not always supported on Android)
     */
    private class TimeOutAsyncTask extends AsyncTask<Void, Void, Void> {

        ExecutePingAsyncTask task;
        private int ttlTask;

        public TimeOutAsyncTask(ExecutePingAsyncTask task, int ttlTask) {
            this.task = task;
            this.ttlTask = ttlTask;
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            if (handlerTimeout == null) {
                handlerTimeout = new Handler();
            }

            // stop old timeout
            if (runnableTimeout != null) {
                handlerTimeout.removeCallbacks(runnableTimeout);
            }
            // define timeout
            runnableTimeout = new Runnable() {
                @Override
                public void run() {
                    if (task != null) {
                        Log.e(MainActivity.tag, ttlTask + " task.isFinished()" + finishedTasks + " " + (ttlTask == finishedTasks));
                        if (ttlTask == finishedTasks) {
                            task.setCancelled(true);
                            task.cancel(true);
//                          context.stopProgressBar();
                        }
                    }
                }
            };
            // launch timeout after a delay
            handlerTimeout.postDelayed(runnableTimeout, TIMEOUT);

            super.onPostExecute(result);
        }
    }

    /**
     * The task that ping an ip, with increasing time to live (ttl) value
     */
    private class ExecutePingAsyncTask extends AsyncTask<Void, Void, String> {

        private boolean isCancelled;
        private int maxTtl;

        public ExecutePingAsyncTask(int maxTtl) {
            this.maxTtl = maxTtl;
        }

        /**
         * Launches the ping, launches InetAddress to retrieve url if there is one, store trace
         */
        @Override
        protected String doInBackground(Void... params) {

            if (hasConnectivity()) {
                try {
                    android.os.Debug.waitingForDebugger();
                    String res = launchPing(urlToPing);

                    TracerouteContainer trace;
                                String ip = parseIpFromPing(res);

                    if (res.contains(UNREACHABLE_PING) && !res.contains(EXCEED_PING)) {
                        // Create the TracerouteContainer object when ping
                        // failed
                        trace = new TracerouteContainer("", ip, elapsedTime, false);
                    } else {
                        // Create the TracerouteContainer object when succeed
                        trace = new TracerouteContainer("", ip, ttl == maxTtl ? Float.parseFloat(parseTimeFromPing(res))
                                : elapsedTime, true);
                    }

                    // Get the host name from ip (unix ping do not support
                    // hostname resolving)
                    InetAddress inetAddr = InetAddress.getByName(trace.getIp());
                    String hostname = inetAddr.getHostName();
                    String canonicalHostname = inetAddr.getCanonicalHostName();
                    trace.setHostname(hostname);
                                       latestTrace = trace;
                                       Log.d(MainActivity.tag, "hostname : " + hostname);
                    Log.d(MainActivity.tag, "canonicalHostname : " + canonicalHostname);

                    // Store the TracerouteContainer object
                    Log.d(MainActivity.tag, trace.toString());

                                // Not refresh list if this ip is the final ip but the ttl is not maxTtl
                                // this row will be inserted later
                                /*if (!ip.equals(ipToPing) || ttl == maxTtl) {
                                    context.refreshList(trace);
                                }*/

                    return res;
                } catch (final Exception e) {

                }
            } else {
                return context.getString(R.string.no_connectivity_trace);

            }
            return "";
        }

        /**
         * Launches ping command
         * @param url
         * The url to ping
         * @return The ping string
         */
        @SuppressLint("NewApi")
        private String launchPing(String url) throws Exception {
            // Build ping command with parameters
            Process p;
            String command = "";

            String format = "ping -c 1 -t %d ";
            command = String.format(format, ttl);

            Log.d(MainActivity.tag, "Will launch : " + command + url);

            long startTime = System.nanoTime();
            elapsedTime = 0;
            // timeout task
            new TimeOutAsyncTask(this, ttl).execute();
            // Launch command
            p = Runtime.getRuntime().exec(command + url);
            Log.d("PING", url);
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

            // Construct the response from ping
            String s;
            String res = "";
            while ((s = stdInput.readLine()) != null) {
                Log.d("buffer", s);
                res += s + "\n";
                if (s.contains(FROM_PING) || s.contains(SMALL_FROM_PING)) {
                    // We store the elapsedTime when the line from ping comes
                    elapsedTime = (System.nanoTime() - startTime) / 1000000.0f;
                }
            }

            p.destroy();

            if (res.equals("")) {
                throw new IllegalArgumentException();
            }

            // Store the wanted ip adress to compare with ping result
            if (ttl == 1) {
                ipToPing = parseIpToPingFromPing(res);
                Log.v("IP", ipToPing);
            }

            return res;
        }

        /**
         * Treat the previous ping (launches a ttl+1 if it is not the final ip, refresh the list on view etc...)
         */
        @Override
        protected void onPostExecute(String result) {
            if (!isCancelled) {
                try {
                    if (!"".equals(result)) {
                        if (context.getString(R.string.no_connectivity_trace).equals(result)) {
                            Toast.makeText(context, context.getString(R.string.no_connectivity_trace), Toast.LENGTH_SHORT).show();
                        } else {
                            Log.d(MainActivity.tag, result);

                            if (latestTrace != null && latestTrace.getIp().equals(ipToPing)) {
                                if (ttl < maxTtl) {
                                    ttl = maxTtl;
                                    new ExecutePingAsyncTask(maxTtl).execute();
                                } else {

                                }
                            } else {
                                if (ttl < maxTtl) {
                                    ttl++;
                                    new ExecutePingAsyncTask(maxTtl).execute();
                                }
                            }
//                          context.refreshList(traces);

                        }
                    }
                    finishedTasks++;
                } catch (final Exception e) {

                }
            }

            super.onPostExecute(result);
        }

        /**
         * Handles exception on ping
         * 
         * @param e
         *            The exception thrown
         */
        private void onException(Exception e) {
            Log.e(MainActivity.tag, e.toString());

            if (e instanceof IllegalArgumentException) {
                Toast.makeText(context, context.getString(R.string.no_ping), Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, context.getString(R.string.error_trace), Toast.LENGTH_SHORT).show();
            }



            finishedTasks++;
        }

        public void setCancelled(boolean isCancelled) {
            this.isCancelled = isCancelled;
        }

    }

    /**
     * Gets the ip from the string returned by a ping
     * 
     * @param ping
     *            The string returned by a ping command
     * @return The ip contained in the ping
     */
    private String parseIpFromPing(String ping) {
        String ip = "";
        if (ping.contains(FROM_PING)) {
            // Get ip when ttl exceeded
            int index = ping.indexOf(FROM_PING);

            ip = ping.substring(index + 5);
            if (ip.contains(PARENTHESE_OPEN_PING)) {
                // Get ip when in parenthese
                int indexOpen = ip.indexOf(PARENTHESE_OPEN_PING);
                int indexClose = ip.indexOf(PARENTHESE_CLOSE_PING);

                ip = ip.substring(indexOpen + 1, indexClose);
            } else {
                // Get ip when after from
                ip = ip.substring(0, ip.indexOf("\n"));
                if (ip.contains(":")) {
                    index = ip.indexOf(":");
                } else {
                    index = ip.indexOf(" ");
                }

                ip = ip.substring(0, index);
            }
        } else {
            // Get ip when ping succeeded
            int indexOpen = ping.indexOf(PARENTHESE_OPEN_PING);
            int indexClose = ping.indexOf(PARENTHESE_CLOSE_PING);

            ip = ping.substring(indexOpen + 1, indexClose);
        }

        return ip;
    }

    /**
     * Gets the final ip we want to ping (example: if user fullfilled google.fr, final ip could be 8.8.8.8)
     * 
     * @param ping
     *            The string returned by a ping command
     * @return The ip contained in the ping
     */
    private String parseIpToPingFromPing(String ping) {
        String ip = "";
        if (ping.contains(PING)) {
            // Get ip when ping succeeded
            int indexOpen = ping.indexOf(PARENTHESE_OPEN_PING);
            int indexClose = ping.indexOf(PARENTHESE_CLOSE_PING);

            ip = ping.substring(indexOpen + 1, indexClose);
        }

        return ip;
    }

    /**
     * Gets the time from ping command (if there is)
     * 
     * @param ping
     *            The string returned by a ping command
     * @return The time contained in the ping
     */
    private String parseTimeFromPing(String ping) {
        String time = "";
        if (ping.contains(TIME_PING)) {
            int index = ping.indexOf(TIME_PING);

            time = ping.substring(index + 5);
            index = time.indexOf(" ");
            time = time.substring(0, index);
        }

        return time;
    }

    /**
     * Check for connectivity (wifi and mobile)
     *
     * @return true if there is a connectivity, false otherwise
     */
    public boolean hasConnectivity() {


        /*ConnectivityManager connectivityManager = (ConnectivityManager)context.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();*/
        return true;
    }
}

0 个答案:

没有答案