2012-01-30 2 views
5

호스트 (표준 Android 또는 NDK 구현을 통해)에 핑 (ping) 할 수있는 방법이 있으며 응답에 대한 자세한 정보가 있습니까? (시간, TTL이 패키지를 상실 등) 나는이 기능을 가지고 있지만 하나를 찾을 수있는 몇 가지 오픈 소스 애플리케이션의 생각 ...Android ICMP ping

감사

을 는

답변

13

AFAIK, 전송 ICMP ECHO는 요구를 요청 루트 (즉 앱을 setuid해야합니다.) - 이 아니고 현재 "재고"Android (지옥, 심지어 InetAddress#isReachable() Android의 방법은 사양에 따라 작동하지 않습니다 joke)입니다.

는/usr/빈/핑 & 프로세스 사용하는 매우 기본적인 예를

- AsyncTask를를 사용하여, 핑 결과를 읽기는 :

public class PingActivity extends Activity { 
    PingTask mTask; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     mTask = new PingTask(); 
     // Ping the host "android.com" 
     mTask.execute("android.com"); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mTask.stop(); 
    } 

    class PingTask extends AsyncTask<String, Void, Void> { 
     PipedOutputStream mPOut; 
     PipedInputStream mPIn; 
     LineNumberReader mReader; 
     Process mProcess; 
     TextView mText = (TextView) findViewById(R.id.text); 
     @Override 
     protected void onPreExecute() { 
      mPOut = new PipedOutputStream(); 
      try { 
       mPIn = new PipedInputStream(mPOut); 
       mReader = new LineNumberReader(new InputStreamReader(mPIn)); 
      } catch (IOException e) { 
       cancel(true); 
      } 

     } 

     public void stop() { 
      Process p = mProcess; 
      if (p != null) { 
       p.destroy(); 
      } 
      cancel(true); 
     } 

     @Override 
     protected Void doInBackground(String... params) { 
      try { 
       mProcess = new ProcessBuilder() 
        .command("/system/bin/ping", params[0]) 
        .redirectErrorStream(true) 
        .start(); 

       try { 
        InputStream in = mProcess.getInputStream(); 
        OutputStream out = mProcess.getOutputStream(); 
        byte[] buffer = new byte[1024]; 
        int count; 

        // in -> buffer -> mPOut -> mReader -> 1 line of ping information to parse 
        while ((count = in.read(buffer)) != -1) { 
         mPOut.write(buffer, 0, count); 
         publishProgress(); 
        } 
        out.close(); 
        in.close(); 
        mPOut.close(); 
        mPIn.close(); 
       } finally { 
        mProcess.destroy(); 
        mProcess = null; 
       } 
      } catch (IOException e) { 
      } 
      return null; 
     } 
     @Override 
     protected void onProgressUpdate(Void... values) { 
      try { 
       // Is a line ready to read from the "ping" command? 
       while (mReader.ready()) { 
        // This just displays the output, you should typically parse it I guess. 
        mText.setText(mReader.readLine()); 
       } 
      } catch (IOException t) { 
      } 
     } 
    } 
} 
+0

나는 전화를 끊지 않았고 넷 핑 (Net Ping) 앱은 설계대로 작동하고있다. –

+1

그렇다면 [java.lang.Process] (http://developer.android.com/reference/java/lang/Process.html)를 사용하여 ping 명령을 실행할 것입니다.이 명령은 setuid이며 TTL을 제공 할 수 있습니다. 출력을 구문 분석합니다. Java에서 바로 수행하는 것은 효과가 없습니다 (프로세스의 예제는 실제로 ping 명령을 실행하고 있습니다). – Jens

+0

루트없이 java.lang.Process와 함께 'ping'명령을 실행할 수 있습니까? –

0

내가 루트없이 ping 명령을 실행하는 방법을 발견했다.
먼저 '쉬'프로세스를 생성하고 해당 쉘에서 '핑'을 실행 코드 :

p = new ProcessBuilder("sh").redirectErrorStream(true).start(); 

DataOutputStream os = new DataOutputStream(p.getOutputStream()); 
os.writeBytes("ping -c 10 " + host + '\n'); 
os.flush(); 

// Close the terminal 
os.writeBytes("exit\n"); 
os.flush(); 

// read ping replys 
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); 
String line; 

while ((line = reader.readLine()) != null) { 
    System.out.println(line); 
} 

이 사이 애 노젠 모드 7.1.0 (안드로이드 2.3.7)

내 HTC 장치에서 잘 작동
+1

ping 명령에 -w <# seconds>이 없으면 잠재적으로 처리 할 수없는 경우 응답을 얻습니다.이 시도는 경고입니다. –

+1

-1 셸을 만든 다음 핑을 실행하는 것은 좋지 않습니다. 더 많은 구문 분석과 입력이 어려워집니다. ping을 직접 실행하는 것이 좋습니다. –