如何find一个可用的端口?
我想启动一个监听端口的服务器。 我可以明确指定端口,它的工作原理。 但我想自动find一个端口。 在这方面我有两个问题。
-
我应该在哪个范围的端口号码search? (我用端口12345,12346和12347,这很好)。
-
我怎样才能找出一个给定的端口是否没有被其他软件占用?
如果您不介意使用的端口,则将ServerSocket构造函数的端口指定为0,并且将侦听任何空闲端口。
ServerSocket s = new ServerSocket(0); System.out.println("listening on port: " + s.getLocalPort());
如果你想使用一组特定的端口,那么最简单的方法可能是遍历它们直到一个工作。 像这样的东西:
public ServerSocket create(int[] ports) throws IOException { for (int port : ports) { try { return new ServerSocket(port); } catch (IOException ex) { continue; // try next port } } // if the program gets here, no port in the range was found throw new IOException("no free port found"); }
可以这样使用:
try { ServerSocket s = create(new int[] { 3843, 4584, 4843 }); System.out.println("listening on port: " + s.getLocalPort()); } catch (IOException ex) { System.err.println("no available ports"); }
如果您将0作为端口号传递给ServerSocket的构造函数,它将为您分配一个端口。
从Java 1.7开始,你可以像这样使用try-with-resources:
private Integer findRandomOpenPortOnAllLocalInterfaces() throws IOException { try ( ServerSocket socket = new ServerSocket(0); ) { return socket.getLocalPort(); } }
如果您需要在特定接口上查找打开的端口,请检查ServerSocket文档以获取替代构造函数。
警告:使用此方法返回的端口号的任何代码都会受到竞争条件的影响 – 在closuresServerSocket实例后,不同的进程/线程可能会立即绑定到同一个端口。
根据维基百科 ,如果您不需要“知名”端口,则应该使用端口49152
至65535
。
AFAIK确定一个端口正在使用的唯一方法是尝试打开它。
如果你需要在范围内使用:
public int nextFreePort(int from, int to) { int port = randPort(from, to); while (true) { if (isLocalPortFree(port)) { return port; } else { port = ThreadLocalRandom.current().nextInt(from, to); } } } private boolean isLocalPortFree(int port) { try { new ServerSocket(port).close(); return true; } catch (IOException e) { return false; } }
Eclipse SDK包含一个SocketUtil类,它可以做你想做的事情。 你可以看看git的源代码 。
如果你使用Spring,你可以尝试http://docs.spring.io/spring/docs/4.0.5.RELEASE/javadoc-api/org/springframework/util/SocketUtils.html#findAvailableTcpPort–
请参阅http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29
创build绑定到指定端口的服务器套接字。 0的端口在任何空闲端口上创build一个套接字。
这在Java 6上适用于我
ServerSocket serverSocket = new ServerSocket(0); System.out.println("listening on port " + serverSocket.getLocalPort());
如果你想使用ServerSocket
创build你自己的服务器,你可以让它为你select一个自由的端口:
ServerSocket serverSocket = new ServerSocket(0); int port = serverSocket.getLocalPort();
其他服务器实现通常有类似的支持。 例如Jettyselect一个自由端口,除非你明确地设置它:
Server server = new Server(); ServerConnector connector = new ServerConnector(server); // don't call: connector.setPort(port); server.addConnector(connector); server.start(); int port = connector.getLocalPort();
我最近刚刚发布了一个小图书馆,只是考虑到了这一点。 Maven的依赖是:
<dependency> <groupId>me.alexpanov</groupId> <artifactId>free-port-finder</artifactId> <version>1.0</version> </dependency>
安装完成后,可以通过以下方式获取空闲端口号:
int port = FreePortFinder.findFreeLocalPort();
它可能没有什么帮助,但在我的(Ubuntu)机器上,我有一个文件/ etc / services,其中至less有一些应用程序使用/保留的端口被给出。 这些是这些应用程序的标准端口。
没有保证,这些正在运行,只是这些应用程序使用的默认端口(所以你不应该使用它们,如果可能的话)。
定义的端口略多于500个,大约一半的UDP和一半的TCP。
这些文件是由IANA使用信息制作的,请参阅IANA分配的端口号 。
如果您的服务器启动,那么该套接字没有被使用。
编辑
就像是:
ServerSocket s = null ; try { s = new ServerSocket( 0 ); } catch( IOException ioe ){ for( int i = START; i < END ; i++ ) try { s = new ServerSocket( i ); } catch( IOException ioe ){} } // At this point if s is null we are helpless if( s == null ) { throw new IOException( Strings.format("Unable to open server in port range(%d-%d)",START,END)); }