套接字:使用Java发现端口可用性
如何以编程方式确定使用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的答案不再可靠了。 但是,看起来您仍然可以可靠地使用套接字来testing连接。
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类来监听端口。 如果它抛出一个exception,它正被使用。
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(); */ } }
编辑:如果你所要做的只是select一个空闲的端口,那么new SocketServer(0)
会为你find一个。
基于try / catch套接字的解决scheme,可能不会产生准确的结果(套接字地址是“localhost”,在某些情况下,端口可能被占用,而不是回环接口,至less在Windows上,我已经看到这个testing失败保护区被错误地声明为可用)。
有一个很酷的名为SIGAR的库,下面的代码可以帮助你:
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;
在我的情况下,它帮助尝试连接到端口 – 如果服务已经存在,它会作出回应。
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); }
我试过这样的东西,它对我来说真的很好
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"); }
在我的情况下,我不得不使用DatagramSocket类。
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; } }
不要忘记先import
import java.net.DatagramSocket; import java.net.BindException; import java.net.SocketException;
这里的一些答案没有提供正确的结果,对我来说,这个窍门是使用这个类:
https://mina.apache.org/mina-project/apidocs/org/apache/mina/util/AvailablePortFinder.html