Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 查找两个空闲tcp端口_Java_Sockets_Tcp - Fatal编程技术网

Java 查找两个空闲tcp端口

Java 查找两个空闲tcp端口,java,sockets,tcp,Java,Sockets,Tcp,我知道以下代码可以(可能不是很有效)找到Java中的免费TCP端口: public static int findFreePort() { int port; try { ServerSocket socket= new ServerSocket(0); port = socket.getLocalPort(); socket.close(); } catch (Exception e) { port = -1; } re

我知道以下代码可以(可能不是很有效)找到Java中的免费TCP端口:

  public static int findFreePort() {
    int port;
    try {
      ServerSocket socket= new ServerSocket(0);
      port = socket.getLocalPort();
      socket.close(); 
    } catch (Exception e) { port = -1; }
    return port;    
  } 
(SO-)中有一些相关问题

我不明白的是,为什么(或者是否)对这个方法的两个连续调用都保证返回两个不同的端口。例如,这是假定的(搜索对
findFreePort
方法的调用)


这是否正确?

ServerSocket的源代码如下:

我不太清楚它是如何确定端口是否空闲的,但是:

@param port the port number, or <code>0</code> to use any
free port.

因此,一旦分配了第一个端口,即使是分配给您的应用程序,它也不再是免费的。因此,对ServerSocket的连续调用将不会重用该端口,从而保证两个不同的端口。

在Javadoc规范中,我没有看到任何行表示两个连续调用保证返回两个不同的端口

由于ServerSocket已关闭,第二次调用可能会提供相同的端口。从统计上看,这是不可能的,但我认为并非不可能

如果打开两个ServerSocket,获取端口,然后关闭两个ServerSocket,则可以保证获得两个不同的端口(因为创建第二个ServerSocket时第一个端口不是空闲的)

获取n个不同空闲端口的示例方法:

public int[] getFreePorts(int portNumber) throws IOException {
    int[] result = new int[portNumber];
    List<ServerSocket> servers = new ArrayList<ServerSocket>(portNumber);
    ServerSocket tempServer = null;

    for (int i=0; i<portNumber; i++) {
        try {
            tempServer = new ServerSocket(0);
            servers.add(tempServer);
            result[i] = tempServer.getLocalPort();
        } finally {
            for (ServerSocket server : servers) {
                try {
                    server.close();
                } catch (IOException e) {
                    // Continue closing servers.
                }
            }
        }
    }
    return result;
}
public int[]getFreePorts(int端口号)引发IOException{
int[]结果=新int[portNumber];
列表服务器=新的ArrayList(端口号);
ServerSocket tempServer=null;

对于(int i=0;i获取两个不同端口号的一种方法:

  ServerSocket socket1 = new ServerSocket(0);
  port1 = socket1.getLocalPort();
  ServerSocket socket2 = new ServerSocket(0);
  port2 = socket2.getLocalPort();

  socket1.close();
  socket2.close(); 

它的效率与操作系统所能做到的一样高。但是,之后立即关闭ServerSocket是毫无意义的,因为该端口不再保留,可以分配给其他端口。此练习的唯一目的是创建一个ServerSocket,所以只需创建它。

下面是一个用于查找多个可用端口的类s、 它提供了在某些复杂逻辑流中分配单个端口的灵活性(即,当您需要的端口数量可能不是一个简单的数字,而是取决于复杂逻辑时)。它仍然保证您请求的所有端口都是免费的和唯一的(只要您使用该类的同一实例来获取所有端口)

因此,使用此类的方法是创建一个实例。执行您的代码以执行您想要为使用该实例分配端口的任何操作。然后,绑定所有端口后,您可以处置该实例,并在下次使用新实例

public class PortFinder {

/**
 * If you only need the one port you can use this. No need to instantiate the class
 */
public static int findFreePort() throws IOException {
    ServerSocket socket = new ServerSocket(0);
    try {
        return socket.getLocalPort();
    } finally {
        try {
            socket.close();
        } catch (IOException e) {
        }
    }
}

private HashSet<Integer> used = new HashSet<Integer>();

/**
 * Finds a port that is currently free and is guaranteed to be different from any of the
 * port numbers previously returned by this PortFinder instance.
 */
public synchronized int findUniqueFreePort() throws IOException {
    int port;
    do {
        port = findFreePort();
    } while (used.contains(port));
    used.add(port);
    return port;
}

}
公共类PortFinder{
/**
*如果你只需要一个端口,你可以使用这个。不需要实例化这个类
*/
公共静态int findFreePort()引发IOException{
ServerSocket=新的ServerSocket(0);
试一试{
返回socket.getLocalPort();
}最后{
试一试{
socket.close();
}捕获(IOE异常){
}
}
}
使用的私有HashSet=新HashSet();
/**
*查找当前可用且保证与任何其他端口不同的端口
*此PortFinder实例以前返回的端口号。
*/
public synchronized int findUniqueFreePort()引发IOException{
国际港口;
做{
端口=findFreePort();
}while(used.contains(port));
已使用。添加(端口);
返回端口;
}
}

如果有相关问题,您应该引用它们并链接到它们。由于SO_WAIT(一种旨在避免另一进程接收仍在传输中的数据包的机制)的原因,它不会重新分配。默认情况下,如果您关闭TCP端口,则在接下来的2分钟内不会重新分配以允许这些延迟数据包刷新。这是对我来说,这种行为可能很常见,但只是依赖于实现,不是吗?我不知道这是否是一个标准,但肯定是一个很好的安全/隐私措施。但是
findFreePort
打开套接字并在中间关闭它,因此理论上是可用的。在代码中,端口是分配的,但“close()”是方法不允许此端口。然后,它可以恢复(例如,由另一个ServerSocket)。因此,我认为对该方法的另一次调用可能会给出相同的端口号。应该注意的是,即使是此解决方案(以及Noel M的)不是100%万无一失,存在潜在的争用条件。在调用此方法后,调用方最终将尝试使用这些可用端口。但在此期间,可能会有其他进程打开了它。findFreePort()在哪里;方法。@Krist就在那里,PortFinder类的第一个成员。可能我把它放在字段声明之前的不寻常的顺序搞混了。我想你是说
socket1.getLocalPort()
socket2.getLocalPort()