如何使用Java以编程方式确定给定计算机中端口的可用性?
即给定一个端口号,确定它是否已被使用?
这是实现从Apache来骆驼项目:
/** * 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; }
他们还检查DatagramSocket以检查端口是否可用于UDP和TCP.
希望这可以帮助.
对于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; } }
从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); } } } }
如果您不太关心性能,可以尝试使用ServerSocket类在端口上进行侦听.如果它抛出一个异常,它就被使用了.
public static boolean isAvailable(int portNr) { boolean portFree; try (var ignored = new ServerSocket(portNr)) { portFree = true; } catch (IOException e) { portFree = false; } return portFree; }
编辑:如果你要做的就是选择一个免费端口,那么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; } }