如何从Java Android中ping外部IP

Luk*_*s89 53 java android

我正在为Android 2.2开发一个Ping应用程序.

我尝试我的代码,它的工作原理,但只在本地IP,这是我的问题,我想ping外部服务器.

这是我的代码:

  private OnClickListener milistener = new OnClickListener() {
    public void onClick(View v) {
        TextView info = (TextView) findViewById(R.id.info);
        EditText edit = (EditText) findViewById(R.id.edit);
        Editable host = edit.getText();
        InetAddress in;
        in = null;
        // Definimos la ip de la cual haremos el ping
        try {
            in = InetAddress.getByName(host.toString());
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // Definimos un tiempo en el cual ha de responder
        try {
            if (in.isReachable(5000)) {
                info.setText("Responde OK");
            } else {
                info.setText("No responde: Time out");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            info.setText(e.toString());
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

Ping 127.0.0.1 - > OK
Ping 8.8.8.8(谷歌DNS) - >超时

我还将以下行放在Manifest XML上:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议我在哪里做错了吗?

kri*_*688 53

我尝试了以下代码,这对我有用.

private boolean executeCommand(){
        System.out.println("executeCommand");
        Runtime runtime = Runtime.getRuntime();
        try
        {
            Process  mIpAddrProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
            int mExitValue = mIpAddrProcess.waitFor();
            System.out.println(" mExitValue "+mExitValue);
            if(mExitValue==0){
                return true;
            }else{
                return false;
            }
        }
        catch (InterruptedException ignore)
        {
            ignore.printStackTrace();
            System.out.println(" Exception:"+ignore);
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
            System.out.println(" Exception:"+e);
        }
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

  • 这在投入使用时会泄漏内存并递归调用它!您需要手动关闭stdin,stdout和stderr文件描述符.runtime.getInputStream()close()方法.runtime.getOutputStream()close()方法.runtime.getErrorStream()close()方法.使用此命令检查管道泄漏:adb shell ls -l/proc/<pid>/fd.请编辑答案并添加流关闭,我在这个预期的行为中坠毁了好几天.. (6认同)
  • 您是否需要特殊权限才能运行此程序? (2认同)
  • 检查命令的退出值很有用,因为退出0通常表示命令成功。其他任何值均表示存在问题。 (2认同)

Jim*_*ang 11

在Android的命令中运行ping实用程序并解析输出(假设您具有root权限)

请参阅以下Java代码段:

executeCmd("ping -c 1 -w 1 google.com", false);

public static String executeCmd(String cmd, boolean sudo){
    try {

        Process p;
        if(!sudo)
            p= Runtime.getRuntime().exec(cmd);
        else{
            p= Runtime.getRuntime().exec(new String[]{"su", "-c", cmd});
        }
        BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

        String s;
        String res = "";
        while ((s = stdInput.readLine()) != null) {
            res += s + "\n";
        }
        p.destroy();
        return res;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "";

}
Run Code Online (Sandbox Code Playgroud)


Ale*_*sky 11

这是我在其中一个项目中使用的简单ping:

public static class Ping {
    public String net = "NO_CONNECTION";
    public String host = "";
    public String ip = "";
    public int dns = Integer.MAX_VALUE;
    public int cnt = Integer.MAX_VALUE;
}

public static Ping ping(URL url, Context ctx) {
    Ping r = new Ping();
    if (isNetworkConnected(ctx)) {
        r.net = getNetworkType(ctx);
        try {
            String hostAddress;
            long start = System.currentTimeMillis();
            hostAddress = InetAddress.getByName(url.getHost()).getHostAddress();
            long dnsResolved = System.currentTimeMillis();
            Socket socket = new Socket(hostAddress, url.getPort());
            socket.close();
            long probeFinish = System.currentTimeMillis();
            r.dns = (int) (dnsResolved - start);
            r.cnt = (int) (probeFinish - dnsResolved);
            r.host = url.getHost();
            r.ip = hostAddress;
        }
        catch (Exception ex) {
            Timber.e("Unable to ping");
        }
    }
    return r;
}

public static boolean isNetworkConnected(Context context) {
    ConnectivityManager cm =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}

@Nullable
public static String getNetworkType(Context context) {
    ConnectivityManager cm =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork != null) {
        return activeNetwork.getTypeName();
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

用法: ping(new URL("https://www.google.com:443/"), this);

结果: {"cnt":100,"dns":109,"host":"www.google.com","ip":"212.188.10.114","net":"WIFI"}


Eug*_*rwe 7

在我的情况下,ping可以从设备运行,但不能从模拟器运行.我找到了这个文档:http: //developer.android.com/guide/developing/devices/emulator.html#emulatornetworking

关于"本地网络限制"的主题,它说:

"根据环境的不同,仿真器可能无法支持其他协议(例如用于"ping"的ICMP)可能不受支持.目前,仿真器不支持IGMP或多播."

更多信息:http: //groups.google.com/group/android-developers/browse_thread/thread/8657506be6819297

这是QEMU用户模式网络堆栈的已知限制.从原始文档引用:请注意,互联网不能可靠地支持ping,因为它需要root权限.这意味着您只能ping本地路由器(10.0.2.2).


Lum*_*ger 1

也许 ICMP 数据包被您的(移动)提供商阻止。如果此代码在模拟器上不起作用,请尝试通过wireshark或任何其他嗅探器进行嗅探,并在触发 isReachable() 方法时查看线路上发生了什么。

您还可以在设备日志中找到一些信息。