2010-10-11 141 views
42

我正在爲Android 2.2開發Ping應用程序。如何從Java中Ping外部IP Android

我嘗試我的代碼,它的工作原理,但只在本地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()); 
     } 
    } 
}; 

平127.0.0.1 - >確定
平8.8.8.8(谷歌DNS) - >超時

我把下面的行在清單XML太:

<uses-permission android:name="android.permission.INTERNET"></uses-permission> 

任何人都可以建議我在哪裏我做錯了嗎?

+0

更多信息過於^^你在模擬器或者實際設備上測試它?你有互聯網連接啓用?即在真實設備上確保「移動網絡」已激活,並且您已連接互聯網 – Tseng 2010-10-11 10:41:35

+0

我在仿真器和連接到互聯網的實際設備上進行了測試。謝謝。 – Luks89 2010-10-11 10:44:22

+0

你是否正確地解決了這個問題?我有同樣的問題。如果你解決了這個問題,你能不能告訴我。問候 Sanjay – 2011-06-10 16:09:02

回答

1

也許ICMP數據包被您的(移動)提供商阻止。如果這段代碼在模擬器上不起作用,請嘗試通過wireshark或任何其他嗅探器進行嗅探,並在啓動isReachable()方法時查看線路上的情況。

您也可以在設備日誌中找到一些信息。

+0

我已經在通過Wifi連接的Android 2.2平板電腦測試,我不使用任何的媽媽提供者。謝謝。 – Luks89 2010-10-11 11:08:25

+0

然後,您的下一步應該是嗅探您的設備生成的流量(非)。有很多事情可能在這裏出錯...... – Luminger 2010-10-11 11:12:50

+0

這不太可能是由ICMP阻塞引起的,因爲Android文檔稱「InetAddress.isReachable」首先嚐試通過ICMP進行ping操作,如果該操作失敗,它將嘗試ping TCP端口7 (Echo) – Tseng 2010-10-11 13:37:22

7

在我的情況下,ping可以從設備上運行,但不能從模擬器運行。我發現這個文檔: http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking

「本地網絡限制」它說的話題:

「根據不同的環境中,仿真可能不能支持其他 協議(如ICMP ,用於「ping」)可能不支持 。目前,仿真器不支持IGMP或 多播。「

進一步的信息: http://groups.google.com/group/android-developers/browse_thread/thread/8657506be6819297

這是QEMU用戶模式網絡堆棧的已知的限制。 從原始文檔中引用:請注意,ping不可靠地連接到因特網,因爲它需要root權限 。它 意味着你只能ping本地路由器(10.0.2.2)。

8

在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 ""; 

} 
+0

我正在執行ping -c 10(平均10個ping)是否可以逐行顯示?我試圖讓它附加到一個TextView,它通常會附加s到res,但沒有奏效。 – sajattack 2012-08-21 23:43:36

+0

這對我有效。謝謝 – wolfaviators 2015-05-18 20:07:57

43

我嘗試下面的代碼,這對我的作品。

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

我發現這是在4.1上檢查ICMP回顯的唯一可靠方法。 – pipacs 2014-02-01 11:38:17

+1

您是否需要特殊權限才能運行此操作? – htellez 2015-10-31 05:02:22

+0

不要忘記添加權限互聯網: 2015-12-26 08:22:11

-1

使用此代碼:此方法適用於4.3+,也適用於以下版本。

try { 

     Process process = null; 

     if(Build.VERSION.SDK_INT <= 16) { 
      // shiny APIS 
       process = Runtime.getRuntime().exec(
        "/system/bin/ping -w 1 -c 1 " + url); 


     } 
     else 
     { 

        process = new ProcessBuilder() 
       .command("/system/bin/ping", url) 
       .redirectErrorStream(true) 
       .start(); 

      } 



     BufferedReader reader = new BufferedReader(new InputStreamReader(
       process.getInputStream())); 

     StringBuffer output = new StringBuffer(); 
     String temp; 

     while ((temp = reader.readLine()) != null)//.read(buffer)) > 0) 
     { 
      output.append(temp); 
      count++; 
     } 

     reader.close(); 


     if(count > 0) 
      str = output.toString(); 

     process.destroy(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    Log.i("PING Count", ""+count); 
    Log.i("PING String", str); 
1

這就是我實現了我自己,它返回的平均延遲:

/* 
Returns the latency to a given server in mili-seconds by issuing a ping command. 
system will issue NUMBER_OF_PACKTETS ICMP Echo Request packet each having size of 56 bytes 
every second, and returns the avg latency of them. 
Returns 0 when there is no connection 
*/ 
public double getLatency(String ipAddress){ 
    String pingCommand = "/system/bin/ping -c " + NUMBER_OF_PACKTETS + " " + ipAddress; 
    String inputLine = ""; 
    double avgRtt = 0; 

    try { 
     // execute the command on the environment interface 
     Process process = Runtime.getRuntime().exec(pingCommand); 
     // gets the input stream to get the output of the executed command 
     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); 

     inputLine = bufferedReader.readLine(); 
     while ((inputLine != null)) { 
      if (inputLine.length() > 0 && inputLine.contains("avg")) { // when we get to the last line of executed ping command 
       break; 
      } 
      inputLine = bufferedReader.readLine(); 
     } 
    } 
    catch (IOException e){ 
     Log.v(DEBUG_TAG, "getLatency: EXCEPTION"); 
     e.printStackTrace(); 
    } 

    // Extracting the average round trip time from the inputLine string 
    String afterEqual = inputLine.substring(inputLine.indexOf("="), inputLine.length()).trim(); 
    String afterFirstSlash = afterEqual.substring(afterEqual.indexOf('/') + 1, afterEqual.length()).trim(); 
    String strAvgRtt = afterFirstSlash.substring(0, afterFirstSlash.indexOf('/')); 
    avgRtt = Double.valueOf(strAvgRtt); 

    return avgRtt; 
} 
2

平爲谷歌的服務器或任何其他服務器

public boolean isConecctedToInternet() { 

    Runtime runtime = Runtime.getRuntime(); 
    try { 
     Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8"); 
     int  exitValue = ipProcess.waitFor(); 
     return (exitValue == 0); 
    } catch (IOException e)   { e.printStackTrace(); } 
    catch (InterruptedException e) { e.printStackTrace(); } 
    return false; 
} 
+0

從這個代碼的Android版本工作?它會在Android 4.1+上工作 – Arshad 2016-06-24 06:32:27

+0

這不是一個通用的解決方案,因爲它依賴於外部工具。 – arts777 2017-06-16 14:53:05

4

這是一個簡單的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; 
} 

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

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