web-dev-qa-db-fra.com

Comment trouver un port disponible?

Je veux démarrer un serveur qui écoute un port. Je peux spécifier le port explicitement et cela fonctionne. Mais je voudrais trouver un port de manière automatique. À cet égard, j'ai deux questions.

  1. Dans quelle plage de numéros de port dois-je rechercher? (J'ai utilisé les ports 12345, 12346 et 12347 et c'était bien).

  2. Comment savoir si un port donné n'est pas occupé par un autre logiciel?

166
Roman

Si le port utilisé ne vous dérange pas, spécifiez un port de 0 pour le constructeur ServerSocket et il écoutera sur n'importe quel port libre.

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

Si vous souhaitez utiliser un ensemble spécifique de ports, le moyen le plus simple consiste probablement à les parcourir jusqu'à ce que l'un d'entre eux fonctionne. Quelque chose comme ça:

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

Pourrait être utilisé comme suit:

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

Si vous transmettez 0 comme numéro de port au constructeur de ServerSocket, il attribuera un port pour vous.

48
Maurice Perry

À partir de Java 1.7, vous pouvez utiliser des ressources d’essai avec les méthodes suivantes: 

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

    }
  }

Si vous avez besoin de trouver un port ouvert sur une interface spécifique, vérifiez ServerSocket documentation pour d'autres constructeurs. 

Avertissement: Tout code utilisant le numéro de port renvoyé par cette méthode est soumis à une condition de concurrence critique: un processus/thread différent peut être lié au même port immédiatement après la fermeture de l'instance ServerSocket. 

28
Andrei Savu

Selon Wikipedia , vous devez utiliser les ports 49152 à 65535 si vous n'avez pas besoin d'un port "connu".

Autant que je sache, le seul moyen de déterminer si un port est utilisé est d’essayer de l’ouvrir.

23
Andy Johnson

Si vous avez besoin derangeuse:

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;
    }
}
18
Serhii Bohutskyi
16
Michail Nikolaev

Le kit de développement logiciel Eclipse contient une classe SocketUtil qui fait ce que vous voulez. Vous pouvez jeter un oeil sur git code source .

10
jopa

Cela fonctionne pour moi sur Java 6

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

Voir http://Java.Sun.com/j2se/1.4.2/docs/api/Java/net/ServerSocket.html#ServerSocket%28int%29

Crée un socket de serveur, lié au port spécifié. Un port de 0 crée un socket sur n'importe quel port libre. 

6
f1sh

J'ai récemment publié une petite bibliothèque pour faire exactement cela avec des tests à l'esprit . La dépendance à Maven est:

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

Une fois installés, les numéros de port libres peuvent être obtenus via:

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

Si vous voulez créer votre propre serveur en utilisant une ServerSocket, vous pouvez simplement le laisser choisir un port libre pour vous:

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

Les autres implémentations de serveur ont généralement un support similaire. Jetty par exemple, sélectionne un port libre à moins que vous ne le définissiez explicitement:

  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

Cela ne vous aidera peut-être pas beaucoup, mais sur ma machine (Ubuntu), j'ai un fichier/etc/services dans lequel au moins les ports utilisés/réservés par certaines applications sont indiqués. Ce sont les ports standard pour ces applications. 

Aucune garantie que ces applications ne fonctionnent, seuls les ports par défaut utilisés par ces applications (vous ne devez donc pas les utiliser si possible).

Il y a un peu plus de 500 ports définis, environ la moitié UDP et la moitié TCP.

Les fichiers sont créés à l'aide d'informations IANA, voir Numéros de ports attribués par IANA .

3
extraneon

Si votre serveur démarre, ce socket n'a pas été utilisé. 

MODIFIER

Quelque chose comme: 

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