首页 文章

如何找到可用的端口?

提问于
浏览
165

我想启动一个监听端口的服务器 . 我可以明确指定端口,它可以工作 . 但我想以自动方式找到一个端口 . 在这方面,我有两个问题 .

  • 我应该在哪个端口号范围内搜索? (我使用了端口12345,12346和12347,它很好) .

  • 如何确定某个端口是否未被其他软件占用?

14 回答

  • 6

    http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29

    创建绑定到指定端口的服务器套接字 . 端口0在任何空闲端口上创建套接字 .

  • 3

    Eclipse SDK包含一个类SocketUtil,它可以满足您的需求 . 你可以看一下git source code .

  • 3

    这适用于Java 6

    ServerSocket serverSocket = new ServerSocket(0);
        System.out.println("listening on port " + serverSocket.getLocalPort());
    
  • 18

    如果您不介意使用的端口,请将ServerSocket constructor的端口指定为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");
    }
    
  • 10

    如果将0作为端口号传递给ServerSocket的构造函数,它将为您分配一个端口 .

  • 4

    从Java 1.7开始,您可以使用try-with-resources,如下所示:

    private Integer findRandomOpenPortOnAllLocalInterfaces() throws IOException {
        try (
            ServerSocket socket = new ServerSocket(0);
        ) {
          return socket.getLocalPort();
    
        }
      }
    

    如果需要在特定接口上查找开放端口,请检查ServerSocket文档以获取替代构造函数 .

    Warning: 使用此方法返回的端口号的任何代码都会受到竞争条件的影响 - 在关闭ServerSocket实例后,不同的进程/线程可能会立即绑定到同一端口 .

  • 240

    根据Wikipedia,你应该使用端口 4915265535 ,如果你不知道'端口' .

    AFAIK确定端口正在使用的唯一方法是尝试打开它 .

  • 15

    如果您需要 range 使用:

    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;
        }
    }
    
  • 27

    如果您想使用 ServerSocket 创建自己的服务器,您可以让它为您选择一个免费端口:

    ServerSocket serverSocket = new ServerSocket(0);
      int port = serverSocket.getLocalPort();
    

    其他服务器实现通常具有类似的支持Jetty例如选择一个空闲端口,除非你明确设置它:

    Server server = new Server();
      ServerConnector connector = new ServerConnector(server);
      // don't call: connector.setPort(port);
      server.addConnector(connector);
      server.start();
      int port = connector.getLocalPort();
    
  • 4

    我最近发布了一个小型库,用于考虑测试 . Maven依赖是:

    <dependency>
        <groupId>me.alexpanov</groupId>
        <artifactId>free-port-finder</artifactId>
        <version>1.0</version>
    </dependency>
    

    安装后,可通过以下方式获取空闲端口号:

    int port = FreePortFinder.findFreeLocalPort();
    
  • 5

    它可能对你没什么帮助,但在我的(Ubuntu)机器上我有一个文件/ etc / services,其中至少给出了一些应用程序使用/保留的端口 . 这些是这些应用程序的标准端口 .

    不保证这些正在运行,只是这些应用程序使用的默认端口(因此如果可能,您不应该使用它们) .

    定义的端口略多于500个,大约有一半UDP和一半TCP .

    这些文件是使用IANA的信息制作的,请参阅IANA Assigned port numbers .

  • 0

    如果您的服务器启动,则不使用该套接字 .

    EDIT

    就像是:

    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));
    }
    
  • 48

    如果您使用Spring,Michail Nikolaev提供的答案是最简单和最干净的答案,IMO应该被投票 . 为了方便起见,我将使用Springframwework SocketUtils .findAvailableTcpPort()方法添加一个内联示例:

    int randomAvailablePort = SocketUtils.findAvailableTcpPort();

    就这么简单,只需一行:) . 当然,Utils类提供了许多其他有趣的方法,我建议看看文档 .

相关问题