web-dev-qa-db-fra.com

Comment cingler une adresse IP

J'utilise cette partie de code pour exécuter une commande ping sur une adresse IP en Java, mais seule la commande ping sur localhost a abouti. Pour les autres hôtes, le programme indique que l'hôte est inaccessible. J'ai désactivé mon pare-feu, mais le problème persiste.

public static void main(String[] args) throws UnknownHostException, IOException {
    String ipAddress = "127.0.0.1";
    InetAddress inet = InetAddress.getByName(ipAddress);

    System.out.println("Sending Ping Request to " + ipAddress);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");

    ipAddress = "173.194.32.38";
    inet = InetAddress.getByName(ipAddress);

    System.out.println("Sending Ping Request to " + ipAddress);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");
}

La sortie est:

Envoi d'une requête ping à 127.0.0.1
L'hôte est accessible
Envoi d'une requête ping à 173.194.32.38
L'hôte n'est pas accessible

66
Mehdi

Vous ne pouvez pas simplement faire un ping en Java car il repose sur ICMP, qui n'est malheureusement pas pris en charge en Java. 

http://mindprod.com/jgloss/ping.html

Utilisez des sockets à la place

J'espère que ça aide

12
aretai

InetAddress.isReachable() selon javadoc :

".. Une implémentation typique utilisera ICMP ECHO REQUESTs si le privilège Peut être obtenu, sinon elle tentera d'établir une connexion TCP Sur le port 7 (Echo) de l'hôte de destination ..".

L'option n ° 1 (ICMP) nécessite généralement des droits administratifs (root)

56
Arvik

Je pense que ce code va vous aider:

public class PingExample {
    public static void main(String[] args){
        try{
            InetAddress address = InetAddress.getByName("192.168.1.103");
            boolean reachable = address.isReachable(10000);

            System.out.println("Is Host reachable? " + reachable);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}
24

Vérifiez votre connectivité. Sur mon ordinateur, cela affiche REACHABLE pour les deux adresses IP:

Envoi d'une requête ping à 127.0.0.1
L'hôte est accessible
Envoi d'une requête ping à 173.194.32.38
L'hôte est accessible

MODIFIER:

Vous pouvez essayer de modifier le code pour utiliser getByAddress () pour obtenir l'adresse:

public static void main(String[] args) throws UnknownHostException, IOException {
    InetAddress inet;

    inet = InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
    System.out.println("Sending Ping Request to " + inet);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");

    inet = InetAddress.getByAddress(new byte[] { (byte) 173, (byte) 194, 32, 38 });
    System.out.println("Sending Ping Request to " + inet);
    System.out.println(inet.isReachable(5000) ? "Host is reachable" : "Host is NOT reachable");
}

Les méthodes getByName () peuvent tenter une sorte de recherche DNS inversée qui peut ne pas être possible sur votre ordinateur. GetByAddress () peut l'ignorer.

18
Durandal

Cela fonctionnera à coup sûr 

import Java.io.*;
import Java.util.*;

public class JavaPingExampleProgram
{

  public static void main(String args[]) 
  throws IOException
  {
    // create the ping command as a list of strings
    JavaPingExampleProgram ping = new JavaPingExampleProgram();
    List<String> commands = new ArrayList<String>();
    commands.add("ping");
    commands.add("-c");
    commands.add("5");
    commands.add("74.125.236.73");
    ping.doCommand(commands);
  }

  public void doCommand(List<String> command) 
  throws IOException
  {
    String s = null;

    ProcessBuilder pb = new ProcessBuilder(command);
    Process process = pb.start();

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

    // read the output from the command
    System.out.println("Here is the standard output of the command:\n");
    while ((s = stdInput.readLine()) != null)
    {
      System.out.println(s);
    }

    // read any errors from the attempted command
    System.out.println("Here is the standard error of the command (if any):\n");
    while ((s = stdError.readLine()) != null)
    {
      System.out.println(s);
    }
  }

}
12
gYanI

Vous pouvez utiliser cette méthode pour envoyer des requêtes ping aux hôtes sur Windows ou d'autres plates-formes: 

private static boolean ping(String Host) throws IOException, InterruptedException {
    boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");

    ProcessBuilder processBuilder = new ProcessBuilder("ping", isWindows? "-n" : "-c", "1", Host);
    Process proc = processBuilder.start();

    int returnVal = proc.waitFor();
    return returnVal == 0;
}
7
Mohammad Banisaeid


Juste un ajout à ce que d’autres ont donné, même s’ils fonctionnent bien mais dans certains cas, si Internet est lent ou qu’un problème de réseau inconnu existe, certains codes ne fonctionneront pas (isReachable()). Mais ce code mentionné ci-dessous crée un processus qui agit comme un ping de ligne de commande (ping ping) pour Windows. Cela fonctionne pour moi dans tous les cas, essayé et testé.

Code: -

public class JavaPingApp {

public static void runSystemCommand(String command) {

    try {
        Process p = Runtime.getRuntime().exec(command);
        BufferedReader inputStream = new BufferedReader(
                new InputStreamReader(p.getInputStream()));

        String s = "";
        // reading output stream of the command
        while ((s = inputStream.readLine()) != null) {
            System.out.println(s);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {

    String ip = "stackoverflow.com"; //Any IP Address on your network / Web
    runSystemCommand("ping " + ip);
}
}

J'espère que ça aide, à la vôtre !!!

3
mustangDC

Même si cela ne repose pas sur ICMP sous Windows, cette implémentation fonctionne plutôt bien avec la nouvelle Durée API

public static Duration ping(String Host) {
    Instant startTime = Instant.now();
    try {
        InetAddress address = InetAddress.getByName(Host);
        if (address.isReachable(1000)) {
            return Duration.between(startTime, Instant.now());
        }
    } catch (IOException e) {
        // Host not available, nothing to do here
    }
    return Duration.ofDays(1);
}
2
Jerome

Voici une méthode pour exécuter une commande ping sur une adresse IP dans Java qui devrait fonctionner sur les systèmes Windows et Unix:

import org.Apache.commons.lang3.SystemUtils;

import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.util.ArrayList;
import Java.util.List;

public class CommandLine
{
    /**
     * @param ipAddress The internet protocol address to ping
     * @return True if the address is responsive, false otherwise
     */
    public static boolean isReachable(String ipAddress) throws IOException
    {
        List<String> command = buildCommand(ipAddress);
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        Process process = processBuilder.start();

        try (BufferedReader standardOutput = new BufferedReader(new InputStreamReader(process.getInputStream())))
        {
            String outputLine;

            while ((outputLine = standardOutput.readLine()) != null)
            {
                // Picks up Windows and Unix unreachable hosts
                if (outputLine.toLowerCase().contains("destination Host unreachable"))
                {
                    return false;
                }
            }
        }

        return true;
    }

    private static List<String> buildCommand(String ipAddress)
    {
        List<String> command = new ArrayList<>();
        command.add("ping");

        if (SystemUtils.IS_OS_WINDOWS)
        {
            command.add("-n");
        } else if (SystemUtils.IS_OS_UNIX)
        {
            command.add("-c");
        } else
        {
            throw new UnsupportedOperationException("Unsupported operating system");
        }

        command.add("1");
        command.add(ipAddress);

        return command;
    }
}

Assurez-vous d’ajouter Apache Commons Lang à vos dépendances.

1
BullyWiiPlaza

Sous Linux avec Oracle-jdk, le code soumis par l'OP utilise le port 7 lorsqu'il n'est pas root et ICMP lorsqu'il est root. Il fait une vraie requête d'écho ICMP lorsqu'il est exécuté en tant que root, comme indiqué dans la documentation.

Si vous l'exécutez sur une machine MS, vous devrez peut-être exécuter l'application en tant qu'administrateur pour obtenir le comportement ICMP.

1
user176495

Je sais que des réponses ont déjà été données aux entrées précédentes, mais pour quiconque a déjà répondu à cette question, j’ai trouvé un moyen de ne pas utiliser le processus "ping" dans Windows, puis de nettoyer la sortie.

Ce que j’ai fait, c’est d’utiliser la JNA pour appeler la bibliothèque d’assistants IP de Windows afin d’effectuer un écho ICMP.

Voir ma propre réponse à un problème similaire

0
Jgregoire108

J'ai essayé quelques options:

  1. Java InetAddress

InetAddress.getByName(ipAddress), le réseau sous Windows a commencé à mal se comporter après plusieurs tentatives

  1. Java HttpURLConnection

            URL siteURL = new URL(url);
            connection = (HttpURLConnection) siteURL.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(pingTime);
            connection.connect();
    
            code = connection.getResponseCode();
            if (code == 200) {
                code = 200;
            }.
    

C'était fiable mais un peu lent

  1. Fichier batch Windows

J'ai finalement décidé de créer un fichier de commandes sur mon ordinateur Windows avec le contenu suivant: ping.exe -n %echoCount% %pingIp% J'ai ensuite appelé le fichier .bat dans mon code Java à l'aide de

public int pingBat(Network network) {
ProcessBuilder pb = new ProcessBuilder(pingBatLocation);
Map<String, String> env = pb.environment();

env.put(
        "echoCount", noOfPings + "");
env.put(
        "pingIp", pingIp);
File outputFile = new File(outputFileLocation);
File errorFile = new File(errorFileLocation);

pb.redirectOutput(outputFile);

pb.redirectError(errorFile);

Process process;

try {
    process = pb.start();
    process.waitFor();
    String finalOutput = printFile(outputFile);
    if (finalOutput != null && finalOutput.toLowerCase().contains("reply from")) {
        return 200;
    } else {
        return 202;
    }
} catch (IOException e) {
    log.debug(e.getMessage());
    return 203;
} catch (InterruptedException e) {
    log.debug(e.getMessage());
    return 204;
}

}

Cela s'est avéré être le moyen le plus rapide et le plus fiable

0
Felix Oriedo

InetAddress ne renvoie pas toujours la valeur correcte. Il réussit dans le cas d'un hôte local, mais pour d'autres hôtes, cela montre que l'hôte est inaccessible. Essayez d’utiliser la commande ping comme indiqué ci-dessous.

try {
    String cmd = "cmd /C ping -n 1 " + ip + " | find \"TTL\"";        
    Process myProcess = Runtime.getRuntime().exec(cmd);
    myProcess.waitFor();

    if(myProcess.exitValue() == 0) {

    return true;
    }
    else {
        return false;
    }
}
catch (Exception e) {
    e.printStackTrace();
    return false;
}
0