1. ホーム
  2. java

[解決済み] IPアドレスにpingを打つことができるのに、なぜInetAddress.isReachableはfalseを返すのでしょうか?

2022-11-07 10:05:37

質問

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

の-cオプションは ping は、ping が単に一度だけサーバに到達することを試みるようにします (ターミナルで使用する無限 ping とは対照的です)。

これは ホストが到達可能な場合は0 . それ以外の場合は "2" が返されます。

ずっとシンプルですが、もちろんプラットフォームによって異なります。 また、このコマンドを使用するには、特定の権限に関する注意事項があるかもしれませんが、私のマシンでは動作することが分かっています。


以下のことに注意してください。 1) このソリューションは製品品質ではありません。 ちょっとしたハックです。 google がダウンしていたり、インターネットが一時的に遅かったり、あるいは権限やシステム設定におかしなところがあると、偽の否定を返すことがあります (つまり、入力アドレスが到達可能であるにもかかわらず失敗することがあります)。 2) isReachableの失敗は、未解決の問題です。 再び - JVMがホストに到達しようとする方法のため、この執筆の時点でこれを行う完璧な方法はないことを示すいくつかのオンラインリソースがあります - 私は、それが本質的にプラットフォーム特有のタスクであり、単純ではあるものの、JVMによってまだ十分に抽象化されていないのだと思います。