简体   繁体   English

Java - 检查端口是否正在使用而不连接它

[英]Java - Check if a port is in use without connecting to it

My situation: 我的情况:

I have two threads running at the same time, one thread wants to wait until a port is in use by the other thread, which will run through a certain number of steps before it reaches the point where it uses the port. 我有两个线程同时运行,一个线程要等到另一个线程正在使用端口时,另一个线程将运行一定数量的步骤,直到到达使用端口的位置为止。

Another restraint I have to commit to is that the thread going through the steps before it reaches opening the port has no easy communication towards the other thread, as it is in JNI native c code using an API (Hopefully not applicable to the problem, its running through a big method) 我必须承诺的另一个限制是,在线程打开端口之前经过这些步骤的线程与其他线程没有简单的通信,因为它是在使用API​​的JNI本机c代码中(希望不适用于该问题,通过一个大方法运行)

Question: 题:

Is there a way for java to be able to wait until the port is in use? 有没有一种方法可以让Java等待端口被使用? I have looked at stackoverflow's solutions but they have a few problems: 我看过stackoverflow的解决方案,但是它们有一些问题:

  1. Creating a new socket will cause the port to be in use, my other thread will not be able to access this socket. 创建新套接字将导致端口正在使用,我的其他线程将无法访问此套接字。
  2. Using a netstat parser removes portability from the project. 使用netstat解析器会从项目中删除可移植性。

If I have overlooked a stackoverflow answer please scold me for my inability to search or something, anything would be helpful. 如果我忽略了stackoverflow的答案请骂我无法搜索或什么,任何事情都会有所帮助。

Is there a way for java to be able to wait until the port is in use? 有没有一种方法可以让Java等待端口被使用?

Not in pure Java. 不是纯Java。

But assuming that the two threads are running in the same JVM, they can communicate by other means. 但假设两个线程在同一个JVM中运行,它们可以通过其他方式进行通信。 So you could use a shared flag (eg a volatile boolean variable or an AtomicBoolean ) or a CountDownLatch or a Semaphore . 因此,您可以使用共享标志(例如,易失性布尔变量或AtomicBoolean )或CountDownLatchSemaphore You can use any of these to implement a simple where one thread (in effect) tells the other one that it is using the port. 您可以使用这些方法中的任何一种来实现一个简单的方法,其中一个线程(实际上) 告诉另一个线程它正在使用该端口。

(In fact, if you want one thread to wait for the other, a latch is the best choice.) (事实上​​,如果你想让一个线程等待另一个线程,那么一个锁存器是最好的选择。)


This is not the kind of thing that would be easy to do in JNI. 这不是JNI中容易做到的事情。 AFAIK, the netstat program does not use normal syscalls to do this. AFAIK, netstat程序不使用普通的系统调用来执行此操作。 I think it uses either the "/proc" tree or (in old implementations) direct access to kernel memory to get the information it needs. 我认为它使用“ / proc”树或(在旧的实现中)直接访问内核内存来获取所需的信息。 You could replicate this in a native library, but I doubt that you will find an existing library to do this. 您可以在本地库中复制它,但是我怀疑您会找到一个现有的库来执行此操作。 And of course, a Windows implementation would be completely different ... 当然,Windows实现将完全不同......

Have you considered or explored Apache camel ? 您是否考虑或探索过Apache骆驼 Here is the sample code from apache camel to check the port availability. 这是来自Apache骆驼的示例代码,用于检查端口的可用性。 Code is quite simple and clean: 代码非常简单和干净:

/**
 * 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;
}

Code source: http://svn.apache.org/viewvc/camel/trunk/components/camel-test/src/main/java/org/apache/camel/test/AvailablePortFinder.java?view=markup#l130 代码来源: http//svn.apache.org/viewvc/camel/trunk/components/camel-test/src/main/java/org/apache/camel/test/AvailablePortFinder.java?view=markup#l130

Just try to connect to it, and sleep/retry a few times until it succeeds. 只是尝试连接它,睡眠/重试几次,直到它成功。 There is no magic predictor of success. 没有成功的灵丹妙药。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM