Dav*_*ria 89
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
他们还检查DatagramSocket以检查端口是否可用于UDP和TCP.
希望这可以帮助.
eiv*_*ndw 41
对于Java 7,您可以使用try-with-resource来获得更紧凑的代码:
private static boolean available(int port) {
try (Socket ignored = new Socket("localhost", port)) {
return false;
} catch (IOException ignored) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
Twe*_*les 35
从Java 7开始,David Santamaria的答案似乎不再可靠.但是,看起来您仍然可以可靠地使用Socket来测试连接.
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Spe*_*ort 33
如果您不太关心性能,可以尝试使用ServerSocket类在端口上进行侦听.如果它抛出一个异常,它就被使用了.
public static boolean isAvailable(int portNr) {
boolean portFree;
try (var ignored = new ServerSocket(portNr)) {
portFree = true;
} catch (IOException e) {
portFree = false;
}
return portFree;
}
Run Code Online (Sandbox Code Playgroud)
编辑:如果你要做的就是选择一个免费端口,那么new ServerSocket(0)
你会找到一个.
以下解决方案的灵感来自Spring核心的SocketUtils实现(Apache许可证).
与使用Socket(...)
它的其他解决方案相比,它非常快(在不到一秒的时间内测试1000个TCP端口):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这仍然受到 user207421 在 David Santamaria 的答案的评论中指出的竞争条件的影响(此方法关闭 and 返回后,某些东西可能会抢占端口ServerSocket
)DatagramSocket
。