85

コードのこの部分を使用してJavaのIPアドレスにpingを実行していますが、ローカルホストへのpingのみが成功し、他のホストの場合、プログラムはホストに到達できないと表示します。ファイアウォールを無効にしましたが、それでもこの問題が発生します

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

出力は次のとおりです。

127.0.0.1
ホストへのPing要求の
送信は到達可能です173.194.32.38へのPing要求の送信は到達可能
ではありません

4

16 に答える 16

70

InetAddress.isReachable()javadocによると:

「..通常の実装では、特権を取得できる場合はICMP ECHO REQUESTを使用します。それ以外の場合は、宛先ホストのポート7(Echo)でTCP接続を確立しようとします。」

オプション#1(ICMP)には通常、管理者(root)権限が必要です。

于 2012-07-16T16:16:38.283 に答える
38

このコードはあなたを助けると思います:

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();
        }
    }
}
于 2015-04-05T18:26:58.717 に答える
20

接続を確認してください。私のコンピューターでは、これは両方のIPに対してREACHABLEを出力します。

127.0.0.1
ホストへのPingリクエストの
送信に到達可能173.194.32.38
ホストへのPingリクエストの送信に到達可能

編集:

getByAddress()を使用してアドレスを取得するようにコードを変更してみてください。

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

getByName()メソッドは、マシンでは不可能な、ある種の逆引きDNSルックアップを試みる可能性があり、getByAddress()はそれをバイパスする可能性があります。

于 2012-07-16T14:51:32.607 に答える
19

残念ながらJavaではサポートされていないICMPに依存しているため、Javaで単純にpingを実行することはできません。

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

代わりにソケットを使用してください

それが役に立てば幸い

于 2012-07-16T15:48:29.553 に答える
11

それは確かに動作します

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

}
于 2013-01-01T13:27:58.470 に答える
11

この方法を使用して、Windowsおよびその他のプラットフォーム上のホストにpingを実行できます。

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;
}
于 2013-08-03T07:05:06.740 に答える
7

簡単な推奨事項:上記の回答のいくつかで提案されているように、isReachable()を使用せず、システムpingを呼び出します。

長い説明:

  • pingはICMPネットワークプロトコルを使用します。ICMPを使用するには、「rawソケット」が必要です
  • 標準ユーザーは、オペレーティングシステムによってrawソケットの使用を許可されていません
  • 以下はfedora30linuxに適用され、Windowsシステムは類似している必要があります
  • javaがrootとして実行されている場合、isReachable()は実際にICMPping要求を送信します
  • javaがrootとして実行されない場合、isReachable()はエコーポートと呼ばれるTCPポート7に接続しようとします。このサービスは通常は使用されなくなりました。使用しようとすると、不適切な結果が生じる可能性があります。
  • 接続要求に対するあらゆる種類の応答、および拒否(TCPフラグRST)も、isReachable()から「true」を生成します。
  • 一部のファイアウォールは、明示的に開いていないポートに対してRSTを送信します。これが発生した場合、存在すらしていないホストに対してisReachable()==trueを取得します。
  • さらに、必要な機能をJavaプロセスに割り当てようとします。
  • setcap cap_net_raw + eip java実行可能ファイル(rawソケットを使用する権利を割り当てます)
  • テスト: getcapjava実行可能ファイル->'cap_net_raw + eip'(機能が割り当てられています)
  • 実行中のJavaは引き続きTCP要求をポート7に送信します
  • getpcaps pidを使用して実行中のJavaプロセスをチェックすると、実行中のJavaにrawソケット機能がないことがわかります。明らかに、私のsetcapはいくつかのセキュリティメカニズムによって上書きされています
  • セキュリティ要件が増加するにつれて、sbが特にpingの例外を実装しない限り、これはさらに制限される可能性があります(ただし、これまでのところネット上には何も見つかりませんでした)
于 2020-03-06T18:10:56.137 に答える
3


他の人が与えたものに加えて、それらはうまく機能しますが、インターネットが遅いか、未知のネットワークの問題が存在する場合、一部のコードは機能しません(isReachable())。ただし、以下で説明するこのコードは、Windowsへのコマンドラインping(cmd ping)として機能するプロセスを作成します。それはすべての場合に私のために働き、試され、テストされました。

コード:-

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

お役に立てば幸いです、乾杯!!!

于 2015-05-17T14:20:58.313 に答える
3

これはWindowsのICMPに依存していませんが、この実装は新しいDurationAPIで非常にうまく機能します

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);
}
于 2018-08-29T09:02:50.283 に答える
1

oracle-jdkを使用するLinuxでは、OPが送信したコードはrootでない場合はポート7を使用し、rootの場合はICMPを使用します。ドキュメントで指定されているように、rootとして実行すると、実際のICMPエコー要求を実行します。

これをMSマシンで実行している場合、ICMPの動作を取得するには、管理者としてアプリを実行する必要があります。

于 2014-02-06T08:12:32.320 に答える
1

システムでJava機能するIPアドレスにpingを実行する方法は次のとおりです。WindowsUnix

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

Apache Commons Lang必ず依存関係に追加してください。

于 2015-09-17T18:28:39.550 に答える
1

私はこの方法を好みます:

   /**
     *
     * @param host
     * @return true means ping success,false means ping fail.
     * @throws IOException
     * @throws InterruptedException
     */
    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();
        return proc.waitFor(200, TimeUnit.MILLISECONDS);
    }

このようにして、ブロッキング時間を200ミリ秒などの特定の時間に制限できます。

MacOS、Android、Windowsでうまく機能し、JDK1.8で使用する必要があります。

このアイデアはMohammadBanisaeidからのものですが、コメントすることはできません。(コメントするには50の評判が必要です)

于 2020-08-21T09:21:55.360 に答える
0

これは以前のエントリで回答されていることは知っていますが、この質問に答える人は誰でも、Windowsで「ping」プロセスを使用して出力をスクラブする必要がない方法を見つけました。

私がしたことは、JNAを使用してWindowのIPヘルパーライブラリを呼び出してICMPエコーを実行することでした

私自身の同様の問題に対する私自身の答えを参照してください

于 2014-09-18T17:34:11.703 に答える
0

InetAddressは常に正しい値を返すとは限りません。ローカルホストの場合は成功しますが、他のホストの場合、これはホストに到達できないことを示しています。以下のようにpingコマンドを使用してみてください。

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;
}
于 2018-03-02T09:56:13.683 に答える
0

私はいくつかのオプションを試しました:

  1. Java InetAddress

InetAddress.getByName(ipAddress)、Windowsのネットワークは、数回試した後、誤動作し始めました

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

これは信頼できましたが、少し遅いです

  1. Windowsバッチファイル

私はついに次の内容でWindowsマシン上にバッチファイルを作成することに決めました。ping.exe -n %echoCount% %pingIp% 次に、Javaコードで.batファイルを次のように呼び出しました。

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

}

これが最速で最も信頼できる方法であることが証明されました

于 2019-03-27T07:07:48.533 に答える
-3

これは機能するはずです:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Pinger {

private static String keyWordTolookFor = "average";

public Pinger() {
    // TODO Auto-generated constructor stub
}


 public static void main(String[] args) {
 //Test the ping method on Windows.
 System.out.println(ping("192.168.0.1")); }


public String ping(String IP) {
    try {
        String line;
        Process p = Runtime.getRuntime().exec("ping -n 1 " + IP);
        BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
        while (((line = input.readLine()) != null)) {

            if (line.toLowerCase().indexOf(keyWordTolookFor.toLowerCase()) != -1) {

                String delims = "[ ]+";
                String[] tokens = line.split(delims);
                return tokens[tokens.length - 1];
            } 
        }

        input.close();
    } catch (Exception err) {
        err.printStackTrace();
    }
    return "Offline";
}

}

于 2017-03-02T01:22:23.490 に答える