InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Tại sao isReachable
trở lại false
? Tôi có thể ping IP.
InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Tại sao isReachable
trở lại false
? Tôi có thể ping IP.
Câu trả lời:
Phương thức "isReachable" không đáng để tôi sử dụng trong nhiều trường hợp. Bạn có thể cuộn xuống dưới cùng để xem giải pháp thay thế của tôi để kiểm tra đơn giản nếu bạn đang trực tuyến và có khả năng phân giải các máy chủ bên ngoài (tức là google.com) ... Điều này thường hoạt động trên các máy * NIX.
Vấn đề
Có rất nhiều cuộc bàn tán về điều này:
Đây là những câu hỏi tương tự khác:
Phát hiện kết nối internet bằng Java
Làm cách nào để kiểm tra tính khả dụng của Internet trong Java?
Và thậm chí một lỗi được báo cáo về cùng vấn đề này:
Phần 1: Một ví dụ có thể lặp lại của vấn đề
Lưu ý rằng trong trường hợp này, nó không thành công.
//also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd"
InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
for (InetAddress address : addresses) {
if (address.isReachable(10000))
{
System.out.println("Connected "+ address);
}
else
{
System.out.println("Failed "+address);
}
}
//output:*Failed www.google.com/74.125.227.114*
Phần 2: Giải pháp Hackish
Thay vào đó, bạn có thể làm điều này:
// in case of Linux change the 'n' to 'c'
Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
Tùy chọn -c của ping sẽ cho phép ping chỉ cần cố gắng truy cập máy chủ một lần (trái ngược với ping vô hạn mà chúng ta thường sử dụng ở thiết bị đầu cuối).
Điều này sẽ trả về 0 nếu máy chủ có thể truy cập được . Nếu không, bạn sẽ nhận được "2" làm giá trị trả về.
Đơn giản hơn nhiều - nhưng tất nhiên nó là nền tảng cụ thể. Và có thể có một số đặc quyền nhất định khi sử dụng lệnh này - nhưng tôi thấy nó hoạt động trên máy của tôi.
XIN LƯU Ý rằng: 1) Giải pháp này không phải là chất lượng sản xuất. Nó có một chút hack. Nếu google ngừng hoạt động, hoặc internet của bạn tạm thời chậm, hoặc thậm chí có thể có một số điều thú vị trong cài đặt đặc quyền / hệ thống của bạn, nếu có thể trả về âm tính sai (tức là nó có thể bị lỗi mặc dù có thể truy cập được địa chỉ đầu vào). 2) Lỗi isReachable là một vấn đề còn tồn tại. Một lần nữa - có một số tài nguyên trực tuyến chỉ ra rằng không có cách nào "hoàn hảo" để thực hiện việc này tại thời điểm viết bài này, do cách JVM cố gắng tiếp cận các máy chủ - tôi đoán đó là một nhiệm vụ cụ thể về bản chất, mặc dù đơn giản , vẫn chưa được tóm tắt đầy đủ bởi JVM.
isReachable
tôi đang gặp lỗi và sử dụng ping tôi không được phép sử dụng icmp? Bạn đã biết cách đối phó với nó bây giờ chưa?
public boolean waitFor(long timeout, TimeUnit unit)
trong java.lang.Process (@since 1.8)
Tôi đến đây để tìm câu trả lời cho cùng câu hỏi này, nhưng tôi không hài lòng với bất kỳ câu trả lời nào vì tôi đang tìm kiếm một giải pháp độc lập với nền tảng. Đây là mã mà tôi đã viết và độc lập với nền tảng, nhưng yêu cầu thông tin về bất kỳ cổng nào đang mở trên máy khác (mà chúng tôi có hầu hết thời gian).
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try {
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
}
return true;
} catch (IOException ex) {
return false;
}
}
InetAddress.isReachable()
đã làm, thông qua cổng 7, ngoại trừ cổng thứ hai thông minh hơn về IOExceptions
ý nghĩa của các nghĩa khác nhau về khả năng tiếp cận.
InetAddress.isReachable()
đưa đối số cổng vào thư viện tiêu chuẩn. Tôi tự hỏi tại sao nó không được bao gồm?
Nếu bạn chỉ muốn kiểm tra xem nó có được kết nối với internet hay không, hãy sử dụng phương pháp này, Nó trả về true nếu internet được kết nối, Sẽ tốt hơn nếu bạn sử dụng địa chỉ của trang web bạn đang cố gắng kết nối thông qua chương trình.
public static boolean isInternetReachable()
{
try {
//make a URL to a known source
URL url = new URL("http://www.google.com");
//open a connection to that source
HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
//trying to retrieve data from the source. If there
//is no connection, this line will fail
Object objData = urlConnect.getContent();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Chỉ đề cập đến nó một cách rõ ràng vì các câu trả lời khác không. Phần ping của isReachable () yêu cầu quyền root trên Unix. Và như được chỉ ra bởi bestsss trong 4779367 :
Và nếu bạn hỏi tại sao ping từ bash lại không, thì thực ra nó cũng cần. Làm điều đó ls -l / bin / ping.
Vì sử dụng root không phải là một tùy chọn trong trường hợp của tôi, giải pháp là cho phép truy cập vào cổng 7 trong tường lửa vào máy chủ cụ thể mà tôi quan tâm.
Tôi không chắc trạng thái như thế nào khi câu hỏi ban đầu được hỏi vào năm 2012.
Như hiện tại, ping sẽ được thực thi dưới dạng root. Thông qua ủy quyền của tệp thực thi ping, bạn sẽ thấy cờ + s và tiến trình thuộc quyền root, nghĩa là nó sẽ chạy dưới quyền root. chạy ls -liat vào nơi đặt ping và bạn sẽ thấy nó.
Vì vậy, nếu bạn chạy InetAddress.getByName ("www.google.com"). IsReacheable (5000) dưới dạng root, nó sẽ trả về true.
bạn cần ủy quyền thích hợp cho ổ cắm thô, được sử dụng bởi ICMP (giao thức được sử dụng bởi ping)
InetAddress.getByName cũng đáng tin cậy như ping, nhưng bạn cần có quyền thích hợp đối với quy trình để nó chạy bình thường.
Tôi đề xuất rằng cách DUY NHẤT đáng tin cậy để kiểm tra kết nối internet là thực sự kết nối VÀ tải xuống một tệp, HOẶC để phân tích cú pháp đầu ra của lệnh gọi ping hệ điều hành thông qua thi hành (). Bạn không thể dựa vào mã thoát để ping và isReachable () là tào lao.
Bạn không thể dựa vào mã thoát ping vì nó trả về 0 nếu lệnh ping thực thi chính xác. Thật không may, ping thực thi chính xác nếu nó không thể đến được máy chủ đích nhưng nhận được "Máy chủ đích không thể truy cập" từ bộ định tuyến ADSL tại nhà của bạn. Đây là loại trả lời được coi là một lần truy cập thành công, do đó thoát mã = 0. Phải thêm mặc dù đây là trên hệ thống Windows. Chưa kiểm tra * nixes.
private boolean isReachable(int nping, int wping, String ipping) throws Exception {
int nReceived = 0;
int nLost = 0;
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
ArrayList<String> strings = new ArrayList<>();
String data = "";
//
while (scanner.hasNextLine()) {
String string = scanner.nextLine();
data = data + string + "\n";
strings.add(string);
}
if (data.contains("IP address must be specified.")
|| (data.contains("Ping request could not find host " + ipping + ".")
|| data.contains("Please check the name and try again."))) {
throw new Exception(data);
} else if (nping > strings.size()) {
throw new Exception(data);
}
int index = 2;
for (int i = index; i < nping + index; i++) {
String string = strings.get(i);
if (string.contains("Destination host unreachable.")) {
nLost++;
} else if (string.contains("Request timed out.")) {
nLost++;
} else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
nReceived++;
} else {
}
}
return nReceived > 0;
}
nping là số lần thử ping ip (gói tin), nếu bạn có mạng hoặc hệ thống bận, hãy chọn số nping lớn hơn.
wping là thời gian chờ pong từ ip, bạn có thể đặt nó 2000ms
bằng cách sử dụng phương pháp này. u có thể viết như sau:
isReachable(5, 2000, "192.168.7.93");
Hoặc sử dụng cách này:
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
InetAddress.isReachable
là flappy và đôi khi trả về không thể truy cập cho các địa chỉ mà chúng tôi có thể ping.
Tôi đã thử những cách sau:
ping -c 1 <fqdn>
và kiểm tra exit status
.
Hoạt động cho tất cả các trường hợp tôi đã thử InetAddress.isReachable
nhưng không hoạt động.
Vì bạn có thể ping máy tính, quy trình Java của bạn sẽ chạy với đủ đặc quyền để thực hiện kiểm tra. Có thể là do sử dụng các cổng ở phạm vi thấp hơn. Nếu bạn chạy chương trình java của mình với sudo / superuser, tôi cá là nó hoạt động.