2012-01-30 51 views
5

Có cách nào để ping máy chủ (chuẩn Android hoặc qua triển khai NDK) và nhận thông tin chi tiết về phản hồi không? (Thời gian, ttl, mất gói, vv ..) Tôi đã nghĩ đến việc một số ứng dụng mã nguồn mở có tính năng này nhưng không thể tìm thấy bất kỳ ...Android ICMP ping

Cảm ơn

Trả lời

13

Afaik, gửi ICMP ECHO yêu cầu nhu cầu root (tức là ứng dụng cần thiết phải được setuid) - và đó là không phải là hiện có thể trong "cổ phiếu" Android (địa ngục, ngay cả phương pháp InetAddress#isReachable() trong Android là joke không hoạt động theo thông số kỹ thuật).

Một ví dụ rất cơ bản sử dụng/usr/bin/ping & Process - đọc kết quả ping, sử dụng một 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

không. Tôi đã hủy đăng ký điện thoại, ứng dụng Net Ping đang hoạt động như được thiết kế. –

+1

thì có thể thực hiện lệnh ping bằng cách sử dụng [java.lang.Process] (http://developer.android.com/reference/java/lang/Process.html) - lệnh đó được setuid và có thể cung cấp cho bạn TTL nếu bạn phân tích đầu ra - thực hiện nó trực tiếp từ Java sẽ không hoạt động (ví dụ trong Quy trình thực tế đang chạy lệnh ping). – Jens

+0

bạn có thể thực hiện lệnh 'ping' bằng java.lang.Process không có gốc không? –

0

Tôi tìm thấy một cách để thực hiện lệnh ping mà không có gốc.
Tạo ra một quá trình 'sh' đầu tiên, và sau đó thực hiện 'ping' trong vỏ đó, mã:

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); 
} 

Nó hoạt động tốt trên thiết bị HTC của tôi với CyanogenMod 7.1.0 (Android 2.3.7)

+1

Nếu không có -w <# seconds> trên lệnh ping, tôi sẽ bị treo nếu không thể gõ được - Chỉ cần cảnh báo cho những người đang cố gắng .. –

+1

-1 Đó là thiết kế kém để tạo vỏ, sau đó khởi chạy ping. Nó liên quan đến phân tích cú pháp nhiều hơn và khó khăn hơn đi qua trong đầu vào. Tốt hơn nên khởi chạy ping trực tiếp. –

Các vấn đề liên quan