InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Mengapa isReachable
kembali false
? Saya bisa melakukan ping ke IP.
InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Mengapa isReachable
kembali false
? Saya bisa melakukan ping ke IP.
Jawaban:
Metode "isReachable" tidak layak digunakan untuk saya dalam banyak kasus. Anda dapat menggulir ke bawah untuk melihat alternatif saya untuk sekadar menguji jika Anda sedang online dan mampu menyelesaikan host eksternal (yaitu google.com) ... Yang biasanya berfungsi pada mesin * NIX.
Masalah
Ada banyak obrolan tentang ini:
Berikut adalah pertanyaan lain yang serupa:
Dan bahkan bug yang dilaporkan tentang masalah yang sama ini:
Bagian 1: Contoh masalah yang dapat direproduksi
Perhatikan bahwa dalam kasus ini, gagal.
//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*
Bagian 2: Solusi Hackish
Sebagai alternatif, Anda dapat melakukan ini:
// 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);
Opsi ping -c akan memungkinkan ping untuk hanya mencoba menjangkau server sekali (berlawanan dengan ping tak terbatas yang biasa kami gunakan di terminal).
Ini akan mengembalikan 0 jika tuan rumah dapat dijangkau . Jika tidak, Anda akan mendapatkan "2" sebagai nilai pengembalian.
Jauh lebih sederhana - tetapi tentu saja ini khusus platform. Dan mungkin ada peringatan hak istimewa tertentu untuk menggunakan perintah ini - tetapi saya merasa perintah ini berfungsi di komputer saya.
HARAP Perhatikan bahwa: 1) Solusi ini bukan kualitas produksi. Ini sedikit hack. Jika google sedang down, atau internet Anda untuk sementara lambat, atau bahkan jika ada beberapa keanehan dalam pengaturan sistem / hak istimewa Anda, jika bisa mengembalikan negatif palsu (yaitu bisa gagal meskipun alamat input dapat dijangkau). 2) Kegagalan isReachable adalah masalah luar biasa. Sekali lagi - ada beberapa sumber daya online yang menunjukkan bahwa tidak ada cara yang "sempurna" untuk melakukan ini pada saat penulisan ini, karena cara JVM mencoba menjangkau host - saya rasa ini adalah tugas khusus platform yang secara intrinsik, meskipun sederhana , belum cukup diabstraksi oleh JVM.
isReachable
saya gagal dan menggunakan ping saya mendapatkan icmp tidak diizinkan? Apakah Anda tahu bagaimana menghadapinya sekarang?
public boolean waitFor(long timeout, TimeUnit unit)
di java.lang.Process (@since 1.8)
Saya datang ke sini untuk mendapatkan jawaban untuk pertanyaan yang sama ini, tetapi saya tidak puas dengan jawaban mana pun karena saya mencari solusi platform independen. Berikut adalah kode yang saya tulis dan platform independen, tetapi memerlukan informasi tentang port terbuka apa pun di komputer lain (yang sering kami miliki).
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()
telah dilakukan, melalui port 7, kecuali port 7 lebih cerdas tentang apa arti berbagai kemungkinan IOExceptions
dalam hal jangkauan.
InetAddress.isReachable()
kelebihan beban untuk memasukkan argumen port, di perpustakaan standar. Saya bertanya-tanya mengapa itu tidak disertakan?
Jika Anda hanya ingin memeriksa apakah itu terhubung ke internet menggunakan metode ini, Ini mengembalikan true jika internet terhubung, Lebih disukai jika Anda menggunakan alamat situs yang Anda coba sambungkan melalui program.
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;
}
Hanya menyebutkannya secara eksplisit karena jawaban yang lain tidak. Bagian ping dari isReachable () membutuhkan akses root pada Unix. Dan seperti yang ditunjukkan oleh bestsss di 4779367 :
Dan jika Anda bertanya mengapa ping dari bash tidak, sebenarnya itu juga perlu. Lakukan itu ls -l / bin / ping.
Karena menggunakan root bukanlah pilihan dalam kasus saya, solusinya adalah mengizinkan akses ke port 7 di firewall ke server tertentu yang saya minati.
Saya tidak yakin bagaimana keadaannya ketika pertanyaan asli diajukan pada tahun 2012.
Seperti saat ini, ping akan dijalankan sebagai root. Melalui otorisasi ping yang dapat dieksekusi, Anda akan melihat tanda + s, dan proses milik root, yang berarti itu akan berjalan sebagai root. jalankan ls -liat di tempat ping berada dan Anda akan melihatnya.
Jadi, jika Anda menjalankan InetAddress.getByName ("www.google.com"). IsReacheable (5000) sebagai root, ini akan menampilkan true.
Anda memerlukan otorisasi yang tepat untuk soket mentah, yang digunakan oleh ICMP (protokol yang digunakan oleh ping)
InetAddress.getByName sama andalnya dengan ping, tetapi Anda memerlukan izin yang tepat agar prosesnya dapat berjalan dengan baik.
Saya menyarankan bahwa SATU-SATUNYA cara yang dapat diandalkan untuk menguji koneksi internet adalah dengan benar-benar menghubungkan DAN mengunduh file, ATAU untuk mengurai output dari panggilan ping OS melalui exec (). Anda tidak dapat mengandalkan kode keluar untuk ping dan isReachable () adalah omong kosong.
Anda tidak dapat mengandalkan kode keluar ping karena mengembalikan 0 jika perintah ping dijalankan dengan benar. Sayangnya, ping dijalankan dengan benar jika tidak dapat menjangkau host target tetapi mendapatkan "Host tujuan tidak dapat dijangkau" dari router ADSL rumah Anda. Ini adalah jenis balasan yang diperlakukan sebagai hit yang berhasil, jadi kode keluar = 0. Perlu ditambahkan meskipun ini ada di sistem Windows. Tidak dicentang * 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 adalah jumlah mencoba untuk melakukan ping ip (paket), jika Anda memiliki jaringan atau sistem yang sibuk pilih nomor nping yang lebih besar.
wping adalah waktu menunggu pong dari ip, Anda dapat mengaturnya 2000ms
untuk menggunakan metode ini Anda dapat menulis ini:
isReachable(5, 2000, "192.168.7.93");
Atau gunakan cara ini:
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
InetAddress.isReachable
adalah flappy, dan terkadang mengembalikan tidak terjangkau untuk alamat yang dapat kita ping.
Saya mencoba yang berikut ini:
ping -c 1 <fqdn>
dan periksa exit status
.
Berfungsi untuk semua kasus yang saya coba di mana InetAddress.isReachable
tidak berhasil.
Karena Anda dapat melakukan ping ke komputer, proses Java Anda harus berjalan dengan hak yang cukup untuk melakukan pemeriksaan. Mungkin karena penggunaan port di kisaran bawah. Jika Anda menjalankan program java Anda dengan sudo / superuser, saya yakin itu berhasil.