134

Javaを使用して、特定のマシンのポートの可用性をプログラムで判断するにはどうすればよいですか?

つまり、ポート番号を指定して、それがすでに使用されているかどうかを判断しますか?

4

10 に答える 10

94

これは、Apache camelプロジェクトからの実装です。

/**
 * Checks to see if a specific port is available.
 *
 * @param port the port to check for availability
 */
public static boolean available(int port) {
    if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
        throw new IllegalArgumentException("Invalid start port: " + port);
    }

    ServerSocket ss = null;
    DatagramSocket ds = null;
    try {
        ss = new ServerSocket(port);
        ss.setReuseAddress(true);
        ds = new DatagramSocket(port);
        ds.setReuseAddress(true);
        return true;
    } catch (IOException e) {
    } finally {
        if (ds != null) {
            ds.close();
        }

        if (ss != null) {
            try {
                ss.close();
            } catch (IOException e) {
                /* should not be thrown */
            }
        }
    }

    return false;
}

彼らは DatagramSocket もチェックして、ポートが UDP と TCP で利用可能かどうかをチェックしています。

お役に立てれば。

于 2009-01-12T14:31:54.040 に答える
41

Java 7の場合、try-with-resourceを使用してよりコンパクトなコードを作成できます。

private static boolean available(int port) {
    try (Socket ignored = new Socket("localhost", port)) {
        return false;
    } catch (IOException ignored) {
        return true;
    }
}
于 2013-03-11T13:50:15.440 に答える
38

パフォーマンスにあまり関心がない場合は、 ServerSocketクラスを使用してポートでリッスンすることをいつでも試すことができます。例外がスローされた場合、それが使用されている可能性があります。

public static boolean isAvailable(int portNr) {
  boolean portFree;
  try (var ignored = new ServerSocket(portNr)) {
      portFree = true;
  } catch (IOException e) {
      portFree = false;
  }
  return portFree;
}

編集:あなたがしようとしているのが空いているポートを選択するnew ServerSocket(0)ことだけであるなら、あなたのためにそれを見つけるでしょう。

于 2009-01-12T07:47:54.633 に答える
38

Java 7 の時点で、David Santamaria の回答は確実に機能しなくなったようです。ただし、ソケットを確実に使用して接続をテストできるようです。

private static boolean available(int port) {
    System.out.println("--------------Testing port " + port);
    Socket s = null;
    try {
        s = new Socket("localhost", port);

        // If the code makes it this far without an exception it means
        // something is using the port and has responded.
        System.out.println("--------------Port " + port + " is not available");
        return false;
    } catch (IOException e) {
        System.out.println("--------------Port " + port + " is available");
        return true;
    } finally {
        if( s != null){
            try {
                s.close();
            } catch (IOException e) {
                throw new RuntimeException("You should handle this error." , e);
            }
        }
    }
}
于 2012-12-11T18:21:42.160 に答える
3

try/catch ソケット ベースのソリューションでは、正確な結果が得られない可能性があります (ソケット アドレスは "localhost" であり、場合によっては、ループバック インターフェイスではなくポートが "占有" される可能性があり、少なくとも Windows ではこのテストが失敗することがわかりました。利用可能と誤って宣言されたプロト)。

SIGARという名前のクールなライブラリがあり、次のコードで接続できます。

Sigar sigar = new Sigar();
int flags = NetFlags.CONN_TCP | NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT;             NetConnection[] netConnectionList = sigar.getNetConnectionList(flags);
for (NetConnection netConnection : netConnectionList) {
   if ( netConnection.getLocalPort() == port )
        return false;
}
return true;
于 2013-03-12T18:34:57.313 に答える
1

私の場合、ポートへの接続を試みるのに役立ちました。サービスがすでに存在する場合は、応答します。

    try {
        log.debug("{}: Checking if port open by trying to connect as a client", portNumber);
        Socket sock = new Socket("localhost", portNumber);          
        sock.close();
        log.debug("{}: Someone responding on port - seems not open", portNumber);
        return false;
    } catch (Exception e) {         
        if (e.getMessage().contains("refused")) {
            return true;
    }
        log.error("Troubles checking if port is open", e);
        throw new RuntimeException(e);              
    }
于 2012-05-31T05:52:34.567 に答える
0

私の場合、DatagramSocket クラスを使用する必要がありました。

boolean isPortOccupied(int port) {
    DatagramSocket sock = null;
    try {
        sock = new DatagramSocket(port);
        sock.close();
        return false;
    } catch (BindException ignored) {
        return true;
    } catch (SocketException ex) {
        System.out.println(ex);
        return true;
    }
}

最初にインポートすることを忘れないでください

import java.net.DatagramSocket;
import java.net.BindException;
import java.net.SocketException;
于 2017-11-06T13:46:37.097 に答える