2012-03-04 35 views
8

Tôi đang cố gắng tìm hiểu xem các máy chủ cụ thể trên mạng của tôi có thể truy cập được không. mã java của tôi là như sau:Java InetAddress.isReachable() timeout

InetAddress adr = InetAddress.getByName(host); 
if(adr.isReachable(3000)){ 
    System.out.println(host + " is reachable"); 
} 

này hoạt động khá tốt, tuy nhiên nếu tôi làm giảm thời gian chờ để nói 500ms thay vào đó, nó sẽ không chỉ dẫn chương trình có thể truy cập được nữa. Tôi có kế hoạch kiểm tra khá nhiều máy chủ trong một vòng lặp, do đó, có một thời gian chờ thấp là khá quan trọng. Nếu tôi ping host theo cách thủ công từ cửa sổ dòng lệnh, nó mất ít hơn 10ms.

Vậy tại sao phương pháp Java lại cần thời gian chờ cao hơn nhiều để thành công? Có cách nào khác để sử dụng isReachable() không?

Trả lời

5

Điều đó tùy thuộc vào ý nghĩa của bạn về khả năng truy cập. Nếu bạn chỉ tìm thấy những gì có thể tìm thấy các host có thể truy cập được trên các cổng cụ thể, bạn có thể mở một kết nối socket tới cổng đó (ví dụ, tìm tất cả các máy chủ HTTP bằng cách kiểm tra cổng 80). Sử dụng InetAddress.isReachable() phụ thuộc vào việc triển khai thực hiện. Theo javadoc, "Một triển khai điển hình sẽ sử dụng ICMP ECHO YÊU CẦU". Kiểm tra "cổng đã biết" (như http (80), smb (445), v.v.) bằng cách sử dụng Java NIO (không chặn I/O) có thể có hiệu suất cao hơn. Công ty của tôi có một sản phẩm sử dụng quét "cổng đã biết" để tìm các hộp chạy Telnet hoặc SSH, sử dụng NIO và chúng tôi có thể quét khoảng 5000 IP/giây.

+0

Cảm ơn, Về cơ bản có, tôi muốn kết nối với/kiểm tra máy chủ trên cổng 10001 được sử dụng bởi các thiết bị tôi cần tìm. Bạn có thể đưa ra một ví dụ về cách thực hiện kiểm tra cổng đã biết đó không? – Jerome

+1

Vâng, tôi không đi vào thực hiện một phương pháp I/O không chặn (NIO). Nhưng tôi sẽ nói chỉ cần tạo một Socket. Tạo một SocketAddress với IP đích và cổng 10001. Sau đó gọi socket.connect (SocketAddress, timeout) với thời gian chờ thích hợp. Catch TimeOutException. Nếu socket.connect() trả về mà không có ngoại lệ, hãy đóng socket, bạn biết rằng thiết bị đang nghe trên 10001. Đối với một mô hình NIO, hãy xem dự án và các ví dụ mã nguồn mở Netty. – brettw