it-swarm.com.de

Sockets: Ermitteln Sie die Verfügbarkeit von Ports mithilfe von Java

Wie bestimme ich programmgesteuert die Verfügbarkeit eines Ports in einer bestimmten Maschine mit Java?

wenn Sie eine Portnummer angeben, bestimmen Sie, ob sie bereits verwendet wird oder nicht.

109
user54075

Dies ist die Implementierung , die vom Apache Camel -Projekt stammt:

/**
 * Checks to see if a specific port is available.
 *
 * @param port the port to check for availability
 */
public static boolean available(int port) {
    if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
        throw new IllegalArgumentException("Invalid start port: " + port);
    }

    ServerSocket ss = null;
    DatagramSocket ds = null;
    try {
        ss = new ServerSocket(port);
        ss.setReuseAddress(true);
        ds = new DatagramSocket(port);
        ds.setReuseAddress(true);
        return true;
    } catch (IOException e) {
    } finally {
        if (ds != null) {
            ds.close();
        }

        if (ss != null) {
            try {
                ss.close();
            } catch (IOException e) {
                /* should not be thrown */
            }
        }
    }

    return false;
}

Sie prüfen auch das DatagramSocket, um zu prüfen, ob der Port in UDP und TCP verfügbar ist.

Hoffe das hilft.

87

Für Java 7 können Sie try-with-resource für kompakteren Code verwenden:

private static boolean available(int port) {
    try (Socket ignored = new Socket("localhost", port)) {
        return false;
    } catch (IOException ignored) {
        return true;
    }
}
37
eivindw

Es scheint, dass ab Java 7 die Antwort von David Santamaria nicht mehr zuverlässig funktioniert. Es sieht jedoch so aus, als könnten Sie einen Socket immer noch zuverlässig zum Testen der Verbindung verwenden.

private static boolean available(int port) {
    System.out.println("--------------Testing port " + port);
    Socket s = null;
    try {
        s = new Socket("localhost", port);

        // If the code makes it this far without an exception it means
        // something is using the port and has responded.
        System.out.println("--------------Port " + port + " is not available");
        return false;
    } catch (IOException e) {
        System.out.println("--------------Port " + port + " is available");
        return true;
    } finally {
        if( s != null){
            try {
                s.close();
            } catch (IOException e) {
                throw new RuntimeException("You should handle this error." , e);
            }
        }
    }
}
35
TwentyMiles

Wenn Sie sich nicht mit der Leistung beschäftigen, können Sie immer versuchen, einen Port mithilfe der Klasse ServerSocket zu überwachen. Wenn es eine Ausnahmewahrscheinlichkeit gibt, wird es verwendet.

boolean portTaken = false;
    ServerSocket socket = null;
    try {
        socket = new ServerSocket(_port);
    } catch (IOException e) {
        portTaken = true;
    } finally {
        if (socket != null)
            try {
                socket.close();
            } catch (IOException e) { /* e.printStackTrace(); */ }
}

EDIT: Wenn Sie nur einen freien Port auswählen, sucht new SocketServer(0) einen für Sie.

30
Spencer Ruport

Die folgende Lösung basiert auf der SocketUtils - Implementierung von Spring-Core (Apache-Lizenz).

Im Vergleich zu anderen Lösungen, die Socket(...) verwenden, ist dies ziemlich schnell (1000 TCP Ports werden in weniger als einer Sekunde getestet):

public static boolean isTcpPortAvailable(int port) {
    try (ServerSocket serverSocket = new ServerSocket()) {
        // setReuseAddress(false) is required only on OSX, 
        // otherwise the code will not work correctly on that platform          
        serverSocket.setReuseAddress(false);
        serverSocket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), port), 1);
        return true;
    } catch (Exception ex) {
        return false;
    }
}       
6
JMax

Die try/catch-Socket-basierten Lösungen liefern möglicherweise keine genauen Ergebnisse (die Socket-Adresse lautet "localhost") und in einigen Fällen könnte der Port nicht von der Loopback-Schnittstelle "belegt" sein, und zumindest unter Windows habe ich gesehen, dass dieser Test fehlschlägt der Prot fälschlicherweise als verfügbar deklariert).

Es gibt eine coole Bibliothek mit dem Namen SIGAR . Der folgende Code kann Sie anschließen:

Sigar sigar = new Sigar();
int flags = NetFlags.CONN_TCP | NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT;             NetConnection[] netConnectionList = sigar.getNetConnectionList(flags);
for (NetConnection netConnection : netConnectionList) {
   if ( netConnection.getLocalPort() == port )
        return false;
}
return true;
3
Shmil The Cat

In meinem Fall half es, den Port zu versuchen und eine Verbindung herzustellen - wenn der Dienst bereits vorhanden ist, würde er antworten.

    try {
        log.debug("{}: Checking if port open by trying to connect as a client", portNumber);
        Socket sock = new Socket("localhost", portNumber);          
        sock.close();
        log.debug("{}: Someone responding on port - seems not open", portNumber);
        return false;
    } catch (Exception e) {         
        if (e.getMessage().contains("refused")) {
            return true;
    }
        log.error("Troubles checking if port is open", e);
        throw new RuntimeException(e);              
    }
0
Ivan

In meinem Fall musste ich die DatagramSocket-Klasse verwenden.

boolean isPortOccupied(int port) {
    DatagramSocket sock = null;
    try {
        sock = new DatagramSocket(port);
        sock.close();
        return false;
    } catch (BindException ignored) {
        return true;
    } catch (SocketException ex) {
        System.out.println(ex);
        return true;
    }
}

Vergiss nicht, zuerst zu importieren

import Java.net.DatagramSocket;
import Java.net.BindException;
import Java.net.SocketException;
0
kmchmk

Eine Bereinigung der Antwort von David Santamaria:

/**
 * Check to see if a port is available.
 *
 * @param port
 *            the port to check for availability.
 */
public static boolean portIsAvailable(int port) {
    try (var ss = new ServerSocket(port); var ds = new DatagramSocket(port)) {
        return true;
    } catch (IOException e) {
        return false;
    }
}

Dies unterliegt immer noch einer Race-Bedingung, auf die User207421 in den Kommentaren zu David Santamaria hingewiesen hat (etwas könnte den Port ergreifen, nachdem diese Methode die ServerSocket und DatagramSocket geschlossen und zurückgegeben hat).

0
Luke Hutchison