web-dev-qa-db-ja.com

使用可能なポートを見つける方法

ポートをリッスンするサーバーを起動したい。ポートを明示的に指定でき、機能します。しかし、自動的にポートを見つけたいです。この点で、2つの質問があります。

  1. どの範囲のポート番号で検索する必要がありますか? (ポート12345、12346、および12347を使用しましたが、問題ありませんでした)。

  2. 特定のポートが別のソフトウェアによって占有されていないかどうかを確認するにはどうすればよいですか?

174
Roman

使用するポートを気にしない場合は、0のポートを ServerSocketコンストラクター に指定すると、空いているポートでリッスンします。

ServerSocket s = new ServerSocket(0);
System.out.println("listening on port: " + s.getLocalPort());

特定のポートセットを使用する場合、最も簡単な方法は、おそらく、ポートが機能するまでポートを反復処理することです。このようなもの:

public ServerSocket create(int[] ports) throws IOException {
    for (int port : ports) {
        try {
            return new ServerSocket(port);
        } catch (IOException ex) {
            continue; // try next port
        }
    }

    // if the program gets here, no port in the range was found
    throw new IOException("no free port found");
}

次のように使用できます:

try {
    ServerSocket s = create(new int[] { 3843, 4584, 4843 });
    System.out.println("listening on port: " + s.getLocalPort());
} catch (IOException ex) {
    System.err.println("no available ports");
}
249

ServerSocketのコンストラクターにポート番号として0を渡すと、ポートが割り当てられます。

49
Maurice Perry

Java 1.7以降では、次のようなtry-with-resourcesを使用できます。

  private Integer findRandomOpenPortOnAllLocalInterfaces() throws IOException {
    try (
        ServerSocket socket = new ServerSocket(0);
    ) {
      return socket.getLocalPort();

    }
  }

特定のインターフェイスで開いているポートを見つける必要がある場合は、代替コンストラクタの ServerSocket ドキュメントを確認してください。

警告:このメソッドによって返されるポート番号を使用するコードは、競合状態の影響を受けます-直後に別のプロセス/スレッドが同じポートにバインドする場合がありますServerSocketインスタンスを閉じます。

29
Andrei Savu

Wikipedia によると、「よく知られている」ポートが必要ない場合は、ポート49152から65535を使用する必要があります。

知る限り、ポートが使用されているかどうかを判断する唯一の方法は、ポートを開こうとすることです。

23
Andy Johnson

rangeで必要な場合:

public int nextFreePort(int from, int to) {
    int port = randPort(from, to);
    while (true) {
        if (isLocalPortFree(port)) {
            return port;
        } else {
            port = ThreadLocalRandom.current().nextInt(from, to);
        }
    }
}

private boolean isLocalPortFree(int port) {
    try {
        new ServerSocket(port).close();
        return true;
    } catch (IOException e) {
        return false;
    }
}
20
19

Eclipse SDKには、クラス SocketUtil が含まれています。 git source code をご覧ください。

10
jopa

これはJava 6で動作します

    ServerSocket serverSocket = new ServerSocket(0);
    System.out.println("listening on port " + serverSocket.getLocalPort());
6
Peter Lawrey

http://Java.Sun.com/j2se/1.4.2/docs/api/Java/net/ServerSocket.html#ServerSocket%28int%29 を参照してください

指定されたポートにバインドされたサーバーソケットを作成します。ポート0は、空きポートにソケットを作成します。

6
f1sh

私は最近、テストを念頭に置いてそれを行うための小さなライブラリをリリースしました。 Mavenの依存関係は次のとおりです。

<dependency>
    <groupId>me.alexpanov</groupId>
    <artifactId>free-port-Finder</artifactId>
    <version>1.0</version>
</dependency>

インストールすると、次の方法で無料のポート番号を取得できます。

int port = FreePortFinder.findFreeLocalPort();
4
Alex Panov

ServerSocketを使用して独自のサーバーを作成する場合は、無料のポートを選択するだけで済みます。

  ServerSocket serverSocket = new ServerSocket(0);
  int port = serverSocket.getLocalPort();

通常、他のサーバー実装には同様のサポートがあります。 Jettyたとえば、明示的に設定しない限り、空きポートを選択します。

  Server server = new Server();
  ServerConnector connector = new ServerConnector(server);
  // don't call: connector.setPort(port);
  server.addConnector(connector);
  server.start();
  int port = connector.getLocalPort();
4
oberlies

あまり役に立たないかもしれませんが、私の(Ubuntu)マシンには/ etc/servicesファイルがあり、少なくともいくつかのアプリで使用/予約されているポートが指定されています。これらは、これらのアプリの標準ポートです。

これらが実行されていることを保証するものではなく、これらのアプリが使用するデフォルトのポートのみです(したがって、可能であれば使用しないでください)。

500個を少し超えるポートが定義されており、UDPとTCPの約半分です。

ファイルは、IANAによる情報を使用して作成されます。 IANA割り当てポート番号 を参照してください。

3
extraneon

サーバーが起動する場合、そのソケットは使用されていません。

編集

何かのようなもの:

ServerSocket s = null ;

try { 
    s = new ServerSocket( 0 ); 
} catch( IOException ioe ){
   for( int i = START; i < END ; i++ ) try {
        s = new ServerSocket( i );
    } catch( IOException ioe ){}
}
// At this point if s is null we are helpless
if( s == null ) {
    throw new IOException(
       Strings.format("Unable to open server in port range(%d-%d)",START,END));
}
3
OscarRyz

Springを使用している場合、Michail Nikolaevが提供する答えは最も単純でクリーンなものであり、IMOは支持されるべきです。便宜上、SpringframweworkSocketUtils 。findAvailableTcpPort()メソッドを使用してインラインの例を追加します。

int randomAvailablePort = SocketUtils.findAvailableTcpPort();

それと同じくらい簡単で、たった1行です:)。もちろん、Utilsクラスには他にも多くの興味深いメソッドがあります。ドキュメントをご覧になることをお勧めします。

1
Gerardo Roza