it-swarm.com.de

Wie finde ich einen verfügbaren Hafen?

Ich möchte einen Server starten, der einen Port abhört. Ich kann port explizit angeben und es funktioniert. Aber ich würde gerne automatisch einen Hafen finden. In dieser Hinsicht habe ich zwei Fragen.

  1. In welchem ​​Bereich von Portnummern sollte ich suchen? (Ich habe die Ports 12345, 12346 und 12347 verwendet und es war in Ordnung).

  2. Wie kann ich herausfinden, ob ein bestimmter Port nicht mit einer anderen Software belegt ist?

166
Roman

Wenn Sie sich nicht für den verwendeten Port interessieren, geben Sie dem ServerSocket-Konstruktor einen Port von 0 an, und der freie Port wird überwacht.

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

Wenn Sie einen bestimmten Satz von Ports verwenden möchten, ist es wahrscheinlich der einfachste Weg, sie zu durchlaufen, bis einer funktioniert. Etwas wie das:

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

Könnte so verwendet werden:

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

Wenn Sie dem Konstruktor von ServerSocket 0 als Portnummer übergeben, wird Ihnen ein Port zugewiesen.

48
Maurice Perry

Ab Java 1.7 können Sie try-with-resources wie folgt verwenden:

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

    }
  }

Wenn Sie einen offenen Port an einer bestimmten Schnittstelle suchen müssen, überprüfen Sie ServerSocket die Dokumentation für alternative Konstruktoren.

Warnung: Jeder Code, der die von dieser Methode zurückgegebene Portnummer verwendet, unterliegt einer Race-Bedingung. Ein anderer Prozess/Thread kann unmittelbar danach an denselben Port gebunden werden Wir schließen die ServerSocket-Instanz.

31
Andrei Savu

Laut Wikipedia sollten Sie die Ports 49152 bis 65535 verwenden, wenn Sie keinen "bekannten" Port benötigen.

AFAIK Die einzige Möglichkeit festzustellen, ob ein Port verwendet wird, besteht darin, zu versuchen, ihn zu öffnen.

23
Andy Johnson

Wenn Sie inrangeverwenden müssen:

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
16

Das Eclipse-SDK enthält eine Klasse SocketUtil , die Ihren Wünschen entspricht. Sie können einen Blick in den git source code werfen.

10
jopa

Dies funktioniert für mich auf Java 6

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

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

Erstellt einen Server-Socket, der an den angegebenen Port gebunden ist. Ein Port von 0 erstellt einen Socket an einem beliebigen freien Port. 

6
f1sh

Ich habe vor kurzem eine kleine Bibliothek veröffentlicht, um genau das zu tun, um Tests durchzuführen. Die Maven-Abhängigkeit ist:

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

Nach der Installation können Sie freie Portnummern erhalten über:

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

Wenn Sie einen eigenen Server mit einer ServerSocket erstellen möchten, können Sie diesen einfach einen freien Port für Sie auswählen:

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

Andere Serverimplementierungen werden normalerweise ähnlich unterstützt. Jetty wählt beispielsweise einen freien Port aus, es sei denn, Sie haben dies ausdrücklich festgelegt:

  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

Es kann Ihnen nicht viel helfen, aber ich habe auf meinem (Ubuntu) Computer eine Datei/etc/services, in der zumindest die Ports angegeben sind, die von einigen Apps verwendet/reserviert werden. Dies sind die Standardanschlüsse für diese Apps. 

Es kann nicht garantiert werden, dass diese Programme ausgeführt werden, sondern nur die Standardanschlüsse, die diese Apps verwenden. Sie sollten sie daher nicht verwenden, wenn dies möglich ist.

Es sind etwas mehr als 500 Ports definiert, etwa die Hälfte von UDP und von TCP.

Die Dateien werden mit Informationen von IANA erstellt, siehe IANA Zugewiesene Portnummern .

3
extraneon

Wenn Ihr Server startet, wurde dieser Socket nicht verwendet. 

EDIT

So etwas wie: 

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

Wenn Sie Spring verwenden, ist die Antwort von Michail Nikolaev die einfachste und sauberste, und die IMO sollte befürwortet werden. Aus praktischen Gründen füge ich ein Inline-Beispiel mit der Springframwework-Methode SocketUtils . FindAvailableTcpPort () hinzu:

int randomAvailablePort = SocketUtils.findAvailableTcpPort();

So einfach ist das, nur eine Zeile :). Natürlich bietet die Utils-Klasse viele andere interessante Methoden. Ich schlage vor, die Dokumentation zu lesen.

1
Gerardo Roza