Como encontrar uma porta disponível?

Eu quero começar um servidor que ouve uma porta. Eu posso especificar porta explicitamente e funciona. Mas eu gostaria de encontrar uma porta de maneira automática. A este respeito, tenho duas perguntas.

  1. Em qual intervalo de números de porta devo procurar? (Eu usei as portas 12345, 12346 e 12347 e estava tudo bem).

  2. Como posso descobrir se uma determinada porta não está ocupada por outro software?

Se você não se importar com a porta usada, especifique uma porta 0 para o construtor ServerSocket e ela escutará em qualquer porta livre.

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

Se você quiser usar um conjunto específico de portas, a maneira mais fácil é provavelmente iterá-las até que funcione. Algo assim:

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

Poderia ser usado assim:

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

Se você passar 0 como o número da porta para o construtor do ServerSocket, ele alocará uma porta para você.

A partir do Java 1.7, você pode usar o recurso com resources como este:

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

Se você precisar encontrar uma porta aberta em uma interface específica, verifique a documentação do ServerSocket para construtores alternativos.

Aviso: Qualquer código que use o número da porta retornado por este método está sujeito a uma condição de corrida – um processo / encadeamento diferente pode ser vinculado à mesma porta imediatamente depois de fecharmos a instância ServerSocket.

De acordo com a Wikipedia , você deve usar as portas 49152 a 65535 se não precisar de uma porta ‘bem conhecida’.

AFAIK a única maneira de determinar se uma porta está em uso é tentar abri-la.

Se você precisar de uso em alcance :

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

O Eclipse SDK contém uma class SocketUtil , que faz o que você deseja. Você pode dar uma olhada no código fonte do git.

Consulte http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29

Cria um soquete do servidor, ligado à porta especificada. Uma porta de 0 cria um soquete em qualquer porta livre.

Isso funciona para mim no Java 6

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

Se você quiser criar seu próprio servidor usando um ServerSocket , basta escolher uma porta livre para você:

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

Outras implementações de servidor geralmente têm suporte semelhante. O Jetty, por exemplo, escolhe uma porta livre, a menos que você a defina explicitamente:

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

Recentemente, lancei uma pequena biblioteca para fazer exatamente isso com os testes em mente. A dependência do Maven é:

     me.alexpanov    free-port-finder    1.0  

Uma vez instalado, os números de porta livre podem ser obtidos via:

 int port = FreePortFinder.findFreeLocalPort(); 

Pode não ajudar muito, mas na minha máquina (Ubuntu) eu tenho um arquivo / etc / services em que pelo menos as portas usadas / reservadas por alguns dos aplicativos são fornecidas. Estas são as portas padrão para esses aplicativos.

Não há garantias de que estejam em execução, apenas as portas padrão usadas por esses aplicativos (portanto, você não deve usá-las, se possível).

Existem pouco mais de 500 portas definidas, cerca de metade do UDP e metade do TCP.

Os arquivos são feitos usando informações da IANA, consulte os números de porta atribuídos pela IANA.

Se o servidor for iniciado, esse soquete não será usado.

EDITAR

Algo como:

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