Wie bestimme ich programmgesteuert die Verfügbarkeit eines Ports auf einem bestimmten Computer mithilfe von Java?
dh wenn Sie eine Portnummer angegeben haben, stellen Sie fest, ob diese bereits verwendet wird oder nicht.
Wie bestimme ich programmgesteuert die Verfügbarkeit eines Ports auf einem bestimmten Computer mithilfe von Java?
dh wenn Sie eine Portnummer angegeben haben, stellen Sie fest, ob diese bereits verwendet wird oder nicht.
Antworten:
Dies ist die Implementierung aus dem Apache- Kamelprojekt :
/**
* 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 überprüfen auch das DatagramSocket, um zu überprüfen, ob der Port in UDP und TCP verfügbar ist.
Hoffe das hilft.
ServerSocket
abhörenden Port zu erstellen , sollte dies der Fall sein und der zurückgegeben werden ServerSocket
. Das Erstellen und anschließende Schließen und Zurückgeben bietet keine Garantie dafür, dass ServerSocket
über diesen Port eine nachfolgende erstellt werden kann. Das Gleiche gilt für DatagramSocket
.
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;
}
}
ConnectException: 'connection refused'
, ja sollte es false zurück. Für Zeitüberschreitungen ist nichts gültig, was zurückgegeben werden könnte, da die tatsächliche Antwort nicht bekannt ist. Deshalb ist diese Technik für diesen Zweck nutzlos.
Ab Java 7 scheint die Antwort von David Santamaria nicht mehr zuverlässig zu funktionieren. Es sieht jedoch so aus, als könnten Sie die Verbindung weiterhin zuverlässig mit einem Socket testen.
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);
}
}
}
}
Wenn Sie sich nicht zu sehr mit der Leistung befassen, können Sie jederzeit versuchen, einen Port mit der ServerSocket- Klasse abzuhören . Wenn es eine Ausnahme auslöst, werden die Chancen verwendet.
public static boolean isAvailable(int portNr) {
boolean portFree;
try (var ignored = new ServerSocket(portNr)) {
portFree = true;
} catch (IOException e) {
portFree = false;
}
return portFree;
}
BEARBEITEN: Wenn Sie nur versuchen, einen freien Port auszuwählen new ServerSocket(0)
, finden Sie einen für Sie.
Die folgende Lösung ist von der SocketUtils- Implementierung von Spring-Core (Apache-Lizenz) inspiriert .
Im Vergleich zu anderen Lösungen ist die Verwendung Socket(...)
ziemlich schnell (Testen von 1000 TCP-Ports in weniger als einer Sekunde):
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;
}
}
Die auf Try / Catch-Sockets basierenden Lösungen liefern möglicherweise keine genauen Ergebnisse (die Socket-Adresse lautet "localhost", und in einigen Fällen kann der Port nicht von der Loopback-Schnittstelle "belegt" werden, und zumindest unter Windows ist dieser Test fehlgeschlagen, z der Schutz fälschlicherweise als verfügbar deklariert).
Es gibt eine coole Bibliothek namens SIGAR , der folgende Code kann Sie verbinden:
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;
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 isPortAvailable(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 Rennbedingung, auf die user207421 in den Kommentaren zu David Santamarias Antwort hingewiesen hat (etwas könnte den Port greifen, nachdem diese Methode das ServerSocket
und geschlossen hat DatagramSocket
und zurückkehrt).
In meinem Fall hat es geholfen, eine Verbindung zum Port herzustellen. Wenn der Dienst bereits vorhanden ist, reagiert er.
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);
}
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;
}
}
Vergessen Sie nicht, zuerst zu importieren
import java.net.DatagramSocket;
import java.net.BindException;
import java.net.SocketException;
Ich habe so etwas ausprobiert und es hat bei mir sehr gut funktioniert
Socket Skt;
String host = "localhost";
int i = 8983; // port no.
try {
System.out.println("Looking for "+ i);
Skt = new Socket(host, i);
System.out.println("There is a Server on port "
+ i + " of " + host);
}
catch (UnknownHostException e) {
System.out.println("Exception occured"+ e);
}
catch (IOException e) {
System.out.println("port is not used");
}