2013-08-19 41 views
7

tôi đang cố gắng để đạt được một máy chủ và có đoạn mã sauAlternative tốt nhất cho InetAddress.getByName (host) .isReachable (timeout)

if(!InetAddress.getByName(host).isReachable(TIMEOUT)){ 
    throw new Exception("Host does not exist::"+ hostname); 
} 

Hostname Tôi có thể ping từ các cửa sổ, và cũng đã làm một tracert trên nó và nó trả về tất cả các gói dữ liệu. Nhưng java ném ra ngoại lệ "Host không tồn tại ::";

Giá trị thời gian chờ mà tôi đã thử nghiệm từ 2000ms đến 5000ms. Tôi cũng thử 3000. Nguyên nhân của vấn đề này tôi không thể hiểu được là gì. Tôi nghiên cứu trên mạng và một số nói rằng InetAddress.getByName (host) .isReachable (thời gian) không đáng tin cậy và hoạt động theo hệ thống nội bộ.

Cách thay thế tốt nhất cho điều này nếu điều này đúng. Xin đề nghị.

+0

Máy chủ tôi đang thử nghiệm có thể truy cập và tôi có thể ping nó trong Windows. –

Trả lời

14

Hoặc mở một TCP Socket tới một cổng mà bạn nghĩ là mở (22 cho Linux, 139 cho Windows, vv)

public static boolean isReachableByTcp(String host, int port, int timeout) { 
    try { 
     Socket socket = new Socket(); 
     SocketAddress socketAddress = new InetSocketAddress(host, port); 
     socket.connect(socketAddress, timeout); 
     socket.close(); 
     return true; 
    } catch (IOException e) { 
     return false; 
    } 
} 

Hoặc sử dụng một số hack để gửi một ping thực tế. (Lấy cảm hứng từ đây: http://www.inprose.com/en/content/icmp-ping-in-java)

public static boolean isReachableByPing(String host) { 
    try{ 
     String cmd = ""; 

     if(System.getProperty("os.name").startsWith("Windows")) 
      cmd = "cmd /C ping -n 1 " + host + " | find \"TTL\""; 
     else 
      cmd = "ping -c 1 " + host; 

     Process myProcess = Runtime.getRuntime().exec(cmd); 
     myProcess.waitFor(); 

     return myProcess.exitValue() == 0; 
    } catch(Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 

Cùng hack cho Android có thể được tìm thấy here:

+1

Sự cố với 'ping -n 1' trên Windows là "Máy chủ đích không thể truy cập". kết quả trả về mã thoát là 0, điều này tạo ra nhiều xác thực sai. –

+1

Tôi có thể sử dụng ứng dụng này với android bằng cách nào? –

+0

Ping với Android: http://stackoverflow.com/questions/3905358/how-to-ping-external-ip-from-java-android – Shloim

0

Tôi đã phát hiện ra rằng ping -n 1 hostname là không đáng tin cậy hoặc. Nếu bạn nhận được Reply from X.X.X.X: Destination host unreachable. lệnh thực sự cung cấp một mã thoát là 0, do đó cho bạn nhiều lỗi dương.

Giải pháp là tìm kiếm chuỗi "TTL" trong kết quả, vì nó chỉ tồn tại khi bạn nhận được ping thành công. Bởi vì lệnh có một đường ống, bạn cũng cần phải sử dụng cmd /C.

Dưới đây là một ví dụ (Windows):

public boolean isReachable(String hostname) throws IOException, InterruptedException { 
    Process p = Runtime.getRuntime().exec(
      "cmd /C ping -n 1 "+hostname+" | find \"TTL\"" 
    ); 
    return (p.waitFor() == 0); 
} 

Tôi không chắc chắn của unix tương đương, và không có một máy unix để thử nghiệm trên.

0

Đối với nhà phát triển Android: phương pháp trên không hoạt động nếu inet không khả dụng (chính xác hơn khi bộ nhớ cache DNS chạy trong thời gian chờ); những gì tôi tìm thấy: DSN tra cứu luôn mất khoảng 1 phút.

Mã của tôi là như sau:

TIMEOUT = 5000; 
socket.connect(new InetSocketAddress(ServerDomainName, Port), TIMEOUT); 

Người ta cho rằng connect ném một ngoại lệ thời gian chờ trong khoảng 5 giây, nhưng thời điểm đó là 65 giây khi inet là unreachable (ai đó mô tả nó như là giả inet kết nối : Kết nối cho biết được kết nối, nhưng không thể truy cập được inet).