InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
なぜisReachable
戻るのfalse
ですか?IPをpingできます。
InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
なぜisReachable
戻るのfalse
ですか?IPをpingできます。
回答:
「isReachable」方法は、多くの場合、私のために使用しての価値がされていません。下にスクロールすると、オンラインで外部ホスト(google.comなど)を解決できるかどうかをテストするための代替案が表示されます。これは通常、* NIXマシンで動作するようです。
問題
これについてはたくさんのおしゃべりがあります:
その他の同様の質問は次のとおりです。
そして、これと同じ問題について報告されたバグさえ:
パート1:問題の再現可能な例
この場合、失敗することに注意してください。
//also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd"
InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
for (InetAddress address : addresses) {
if (address.isReachable(10000))
{
System.out.println("Connected "+ address);
}
else
{
System.out.println("Failed "+address);
}
}
//output:*Failed www.google.com/74.125.227.114*
パート2:ハックな回避策
代わりに、これを行うことができます:
// in case of Linux change the 'n' to 'c'
Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
pingの-cオプションを使用すると、pingはサーバーに一度到達することを単純に試みることができます(ターミナルで使用されている無限のpingとは対照的です)。
ホストが到達可能な場合、これは0を返します。そうでない場合、戻り値として「2」が返されます。
はるかに単純ですが、もちろんプラットフォーム固有です。そして、このコマンドを使用することにはいくつかの特権の警告があるかもしれません-私はそれが私のマシンで動作することを発見しました。
注意してください:1)このソリューションは生産品質ではありません。その少しハック。グーグルがダウンしているか、インターネットが一時的に遅い場合、または特権/システム設定にいくつかの機能がある場合でも、偽の否定が返される可能性があります(つまり、入力アドレスに到達可能であっても失敗する可能性があります)。2)isReachableエラーは未解決の問題です。繰り返しますが、JVMがホストに到達しようとする方法が原因で、この記事の執筆時点ではこれを行う「完全な」方法がないことを示すオンラインリソースがいくつかあります。これは本質的にプラットフォーム固有のタスクであり、単純ですが、JVMはまだ十分に抽象化されていません。
isReachable
私は失敗し、pingを使用するとicmpが許可されません?今それをどう扱うか知っていますか?
public boolean waitFor(long timeout, TimeUnit unit)
java.lang.Process(@since 1.8)
この同じ質問に対する回答を得るためにここに来ましたが、プラットフォームに依存しないソリューションを探していたため、どの回答にも満足できませんでした。これが私が書いたプラットフォームに依存しないコードですが、他のマシンで開いているポートに関する情報が必要です(ほとんどの場合)。
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try {
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
}
return true;
} catch (IOException ex) {
return false;
}
}
InetAddress.isReachable()
考えられるさまざまなIOExceptions
意味について後者がよりインテリジェントであることを除いて、ポート7を介してすでに行っているものと同じです。
InetAddress.isReachable()
標準ライブラリにポート引数を含めるためにオーバーロードされたら素晴らしいと思います。なぜ含まれていなかったのでしょうか?
インターネットに接続されているかどうかを確認するだけの場合は、このメソッドを使用します。インターネットに接続されている場合はtrueを返します。プログラムを介して接続しようとしているサイトのアドレスを使用する場合に適しています。
public static boolean isInternetReachable()
{
try {
//make a URL to a known source
URL url = new URL("http://www.google.com");
//open a connection to that source
HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
//trying to retrieve data from the source. If there
//is no connection, this line will fail
Object objData = urlConnect.getContent();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
他の答えはそうではないので、それを明示的に言及するだけです。isReachable()のping部分には、UNIXでのrootアクセスが必要です。そして、4779367のbestsssによって指摘されたように:
また、bashからのpingが実行されない理由を尋ねると、実際にはそれも必要です。ls -l / bin / pingを実行します。
私の場合、ルートの使用はオプションではなかったので、解決策は、ファイアウォールのポート7へのアクセスを、私が興味を持っていた特定のサーバーに許可することでした。
2012年に最初の質問が行われたときの状態はわかりません。
現在のところ、pingはルートとして実行されます。ping実行可能ファイルの承認により、+ sフラグと、rootに属するプロセスが表示されます。つまり、rootとして実行されます。pingが置かれている場所でls -liatを実行すると、表示されるはずです。
したがって、ルートとしてInetAddress.getByName( "www.google.com")。isReacheable(5000)を実行すると、trueが返されます。
ICMP(pingで使用されるプロトコル)で使用されるrawソケットに適切な認証が必要です。
InetAddress.getByNameはpingと同じくらい信頼できますが、プロセスを適切に実行するには、プロセスに対する適切な権限が必要です。
インターネット接続をテストする唯一の信頼できる方法は、実際に接続してファイルをダウンロードするか、exec()を介してOS ping呼び出しの出力を解析することです。pingの終了コードに依存することはできず、isReachable()はがらくたです。
pingコマンドが正しく実行されると0が返されるため、ping終了コードに依存することはできません。残念ながら、pingはターゲットホストに到達できない場合でも正しく実行されますが、ホームADSLルーターから「宛先ホストに到達できません」と表示されます。これは、成功したヒットとして扱われる応答の一種なので、終了コード= 0です。これはWindowsシステム上にあることを追加する必要があります。チェックされていません* nixes。
private boolean isReachable(int nping, int wping, String ipping) throws Exception {
int nReceived = 0;
int nLost = 0;
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
ArrayList<String> strings = new ArrayList<>();
String data = "";
//
while (scanner.hasNextLine()) {
String string = scanner.nextLine();
data = data + string + "\n";
strings.add(string);
}
if (data.contains("IP address must be specified.")
|| (data.contains("Ping request could not find host " + ipping + ".")
|| data.contains("Please check the name and try again."))) {
throw new Exception(data);
} else if (nping > strings.size()) {
throw new Exception(data);
}
int index = 2;
for (int i = index; i < nping + index; i++) {
String string = strings.get(i);
if (string.contains("Destination host unreachable.")) {
nLost++;
} else if (string.contains("Request timed out.")) {
nLost++;
} else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
nReceived++;
} else {
}
}
return nReceived > 0;
}
npingはping ip(packets)へのpingの試行回数です。ネットワークまたはシステムがビジーな場合は、より大きなnping番号を選択してください。
wpingは、IPからのポンを待つ時間です。
このメソッドを使用するために2000ミリ秒に設定 できます。
isReachable(5, 2000, "192.168.7.93");
または、この方法を使用します:
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
InetAddress.isReachable
ゆるいです、そして私たちがpingすることができるアドレスのために時々到達不能を返します。
私は以下を試しました:
ping -c 1 <fqdn>
を確認してくださいexit status
。
私が試したすべてのケースでInetAddress.isReachable
機能しますが、機能しません。