代码之家  ›  专栏  ›  技术社区  ›  Roman

如何找到可用端口?

  •  168
  • Roman  · 技术社区  · 15 年前

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

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

    2. 如何确定给定端口是否未被其他软件占用?

    14 回复  |  直到 6 年前
        1
  •  244
  •   Graham Edgecombe    10 年前

    如果不介意使用的端口,请指定0到 ServerSocket constructor 它将监听任何自由端口。

    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");
    }
    
        2
  •  48
  •   Maurice Perry    15 年前

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

        3
  •  28
  •   Andrei Savu    10 年前

    从Java 1.7开始,您可以使用这样的资源:

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

    如果需要在特定接口上找到打开的端口,请检查 ServerSocket 备选施工人员的文件。

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

        4
  •  23
  •   Ahmed Ashour chim    8 年前

    根据 Wikipedia ,您应该使用端口 49152 65535 如果你不需要一个“众所周知”的港口。

    afaik确定端口使用时间的唯一方法是尝试打开它。

        5
  •  18
  •   Serhii Bohutskyi    9 年前

    如果你需要 范围 用途:

    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;
        }
    }
    
        7
  •  10
  •   KevinL Mark Adler    10 年前

    Eclipse SDK包含一个类 SocketUtil ,这就是你想要的。你可以看看Git source code .

        8
  •  6
  •   f1sh    15 年前

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

    创建绑定到指定端口的服务器套接字。0的端口在任何可用端口上创建套接字。

        9
  •  6
  •   Peter Lawrey    14 年前

    这对我来说在Java 6上起作用。

        ServerSocket serverSocket = new ServerSocket(0);
        System.out.println("listening on port " + serverSocket.getLocalPort());
    
        10
  •  4
  •   oberlies Jochen Ehret    12 年前

    如果要使用 ServerSocket ,您只需让它为您选择一个自由端口:

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

    其他服务器实现通常也有类似的支持。 码头 例如,选择一个空闲端口,除非您显式设置它:

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

    我最近发布了一个很小的库,因为我在做测试时就考虑到了这一点。 Maven依赖关系是:

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

    安装后,可通过以下方式获得自由端口号:

    int port = FreePortFinder.findFreeLocalPort();
    
        12
  •  3
  •   extraneon    15 年前

    这可能对您没有太大帮助,但在我的(Ubuntu)机器上,我有一个文件/etc/services,其中至少提供了一些应用程序使用/保留的端口。这些是这些应用程序的标准端口。

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

    定义的端口略多于500个,大约一半是UDP,一半是TCP。

    文件由IANA使用信息生成,请参见 IANA Assigned port numbers .

        13
  •  3
  •   OscarRyz    15 年前

    如果服务器启动了,那么就没有使用那个套接字。

    编辑

    类似:

    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));
    }
    
        14
  •  0
  •   Gerardo Roza    6 年前

    如果您使用的是弹簧,答案由 米哈伊尔·尼古拉夫 是最简单、最干净的一个,国际海事组织应该被否决。 为了方便起见,我将使用SpringFramWork添加一个内联示例 SocketUtils .findavailabletcpport()。 方法:

    int randomAvailablePort = SocketUtils.findAvailableTcpPort();

    就这么简单,只要一句话:)。当然,utils类提供了许多其他有趣的方法,我建议您看看docs。