Je veux démarrer un serveur qui écoute un port. Je peux spécifier le port explicitement et cela fonctionne. Mais j'aimerais trouver un port de manière automatique. A cet égard, j'ai deux questions.
Dans quelle plage de numéros de port dois-je rechercher? (J'ai utilisé les ports 12345, 12346 et 12347 et c'était bien).
Comment puis-je savoir si un port donné n'est pas occupé par un autre logiciel?
java
networking
sockets
port
romain
la source
la source
Réponses:
Si le port utilisé ne vous dérange pas, spécifiez un port de 0 au 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 est probablement de 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 ceci:
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"); }
la source
ssh -D 127.0.0.0:0 ...
? Non!), Ce qui est vraiment frustrant. Nous avons dû patcher un certain nombre de bibliothèques / programmes pour les rendre utiles.new ServerSocket(0)
n'est pas différent à cet égard. Il n'y a rien du tout dans votre premier lien à ce sujet. Votre deuxième lien montre simplement une mauvaise pratique. Une fois que vous avez construit le,ServerSocket
vous devez l' utiliser , ne pas le fermer et essayer de réutiliser le même numéro de port. Tout cela est une perte de temps totale, en plus d'être vulnérable aux problèmes de fenêtre temporelle.Si vous passez 0 comme numéro de port au constructeur de ServerSocket, il allouera un port pour vous.
la source
À partir de Java 1.7, vous pouvez utiliser try-with-resources comme ceci:
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, consultez la documentation de ServerSocket pour d'autres constructeurs.
Avertissement: tout code utilisant le numéro de port renvoyé par cette méthode est soumis à une condition de concurrence - un processus / thread différent peut se lier au même port immédiatement après la fermeture de l'instance ServerSocket.
la source
SO_REUSEADDR
. Et il y a une condition de course, mais il est difficile de résoudre ce problème.ServerSocket
avec le même numéro de port, car il aurait pu être utilisé entre-temps. Pourquoi ne pas simplement retourner le réelServerSocket
au lieu de le fermer reste un mystère.ServerSocket
au lieu d'unint
pour le port.Selon Wikipédia , vous devez utiliser les ports
49152
pour65535
si vous n'avez pas besoin d' un port « bien connu ».AFAIK, la seule façon de déterminer si un port est utilisé est d'essayer de l'ouvrir.
la source
Si vous avez besoin d' une utilisation dans la gamme :
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; } }
la source
ServerSockets
en cas de succès, et ne souffre pas des problèmes de fenêtre de synchronisation de ce code.Si vous utilisez Spring, vous pouvez essayer http://docs.spring.io/spring/docs/4.0.5.RELEASE/javadoc-api/org/springframework/util/SocketUtils.html#findAvailableTcpPort--
la source
SpringUtils.findAvailableTcpPort()
fait exactement la même chose recommandée dans d'autres réponses: choisissez un port puis essayeznew ServerSocket(port)
.Le SDK Eclipse contient une classe SocketUtil , qui fait ce que vous voulez. Vous pouvez consulter le code source de git .
la source
Cela fonctionne pour moi sur Java 6
ServerSocket serverSocket = new ServerSocket(0); System.out.println("listening on port " + serverSocket.getLocalPort());
la source
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 gratuits peuvent être obtenus via:
int port = FreePortFinder.findFreeLocalPort();
la source
Voir ServerSocket :
la source
Si votre serveur démarre, ce socket n'a pas été utilisé.
ÉDITER
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)); }
la source
new ServerSocket(0)
ne fonctionne pas pour vous, l'alternative est la suivante. Je pense qu'il y a 85% des possibilités que vous finissez par utiliser ma suggestion.ServerSockets
pour toujours et ne conserve que le dernier qui a réussi. Il faut unebreak
déclaration.Si vous souhaitez créer votre propre serveur en utilisant a
ServerSocket
, vous pouvez simplement lui demander de choisir un port gratuit pour vous:ServerSocket serverSocket = new ServerSocket(0); int port = serverSocket.getLocalPort();
D'autres implémentations de serveur ont généralement un support similaire. Jetty, par exemple, choisit 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();
la source
Cela peut ne pas vous aider 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 des applications sont donnés. Ce sont les ports standard pour ces applications.
Aucune garantie que celles-ci fonctionnent, juste les ports par défaut que ces applications utilisent (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 fournies par l'IANA, voir Numéros de port attribués par l'IANA .
la source
Si vous utilisez Spring, la réponse fournie par Michail Nikolaev est la plus simple et la plus propre, et l'OMI devrait être votée pour. Juste pour des raisons de commodité, j'ajouterai un exemple en ligne en utilisant la méthode Springframwework SocketUtils .findAvailableTcpPort () :
int randomAvailablePort = SocketUtils.findAvailableTcpPort();
C'est aussi simple que ça, juste une ligne :). Bien sûr, la classe Utils offre de nombreuses autres méthodes intéressantes, je suggère de jeter un œil à la documentation.
la source
En utilisant la classe «ServerSocket», nous pouvons identifier si un port donné est utilisé ou libre. ServerSocket fournit un constructeur qui prend un entier (qui est le numéro de port) comme argument et initialise le socket serveur sur le port. Si ServerSocket lève une exception IO, nous pouvons supposer que ce port est déjà utilisé.
L'extrait suivant est utilisé pour obtenir tous les ports disponibles.
for (int port = 1; port < 65535; port++) { try { ServerSocket socket = new ServerSocket(port); socket.close(); availablePorts.add(port); } catch (IOException e) { } }
Lien de référence .
la source
Si vous utilisez Spring Framework, le moyen le plus simple de le faire est:
private Integer laancNotifyPort = SocketUtils.findAvailableTcpPort();
Vous pouvez également définir une plage acceptable, et il recherchera dans cette plage:
private Integer laancNotifyPort = SocketUtils.findAvailableTcpPort(9090, 10090);
Il s'agit d'une méthode pratique qui évite la complexité, mais en interne, elle est similaire à de nombreuses autres réponses sur ce fil.
la source