【问题标题】:Passing parameter from one process to another in Java在Java中将参数从一个进程传递到另一个进程
【发布时间】:2012-06-14 06:35:33
【问题描述】:

我正在编写一个桌面 Java 应用程序,它基本上在系统托盘中运行。此应用程序可以接受命令行参数。如果有一个应用程序的实例正在运行,而另一个实例是通过命令行参数调用的,它只是将它传递给系统托盘中正在运行的进程。

我对如何实现这一点非常迷茫?我见过一些应用程序这样做,但我不记得名字了。我只想传递字符串参数,然后退出。

【问题讨论】:

标签: java


【解决方案1】:

基本上这个想法是在启动时绑定一个本地端口,如果失败连接到它并发送参数。

public class StartOnce {

  public static void main(String args[]) throws IOException {
    SocketAddress addr = new InetSocketAddress("127.0.0.1", 9999);

    try {
        ServerSocket ss = new ServerSocket();
        // tries to bind to localhost:9999
        ss.bind(addr);
        // Ok, I'm the first instance, listen for other instances for update.
        while(true) {
            Socket s = ss.accept();
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            br.close();
            s.close();
        }
    } catch (BindException e) {
        // BindException, tries to send message to the first instance.
        System.out.println("Another instance is running. Say hi.");
        Socket s = new Socket();
        s.connect(addr);
        PrintWriter pw = new PrintWriter(s.getOutputStream());
        pw.println("Hello.");
        for (String arg : args) {
            pw.println(arg);
        }
        pw.close();
        s.close();
    }
  }
}

【讨论】:

  • 正是 AlexR 所说的。这是一个好的开始。我一直在回避使用本地 IPC 的套接字,但它确实似乎是解决这个问题的最佳解决方案。谢谢。
【解决方案2】:

实施此解决方案有 2 个部分:

  1. 检测是否已经有程序实例在运行
  2. 如果程序已在运行,则将字符串参数传递给程序

使用 Sockets 可以同时完成 1 和 2。

你可以做的是让你的程序在你的程序启动时监听一个端口。当你启动另一个程序实例时,它会尝试监听同一个端口,如果该端口被占用,你可以假定已经有一个程序实例在运行。当然,您应该选择一个任何应用程序都不常用的端口。

然后,如果程序的实例已经启动,只需使用 Sockets 将 String 参数传递过来。

【讨论】:

    【解决方案3】:

    换句话说,您希望您的应用程序是单例的。当用户尝试运行另一个应用程序实例时,它应该向已经存在的应用程序发送某种命令。

    您可以按照以下方式进行操作。

    应用程序启动时应该打开服务器套接字到您选择的端口。 如果成功,它应该开始。这是您的应用程序的第一个实例。 如果失败,则表示端口已经很忙,因此您的应用程序的其他实例正在侦听它。在这种情况下,连接到此套接字,发送命令并终止。

    选择端口号时要小心。它应该足够高(>10000)并且不应该被任何其他流行的应用程序使用。选择一些数字,然后尝试用谷歌搜索。

    【讨论】:

    • 为什么是> 10000?我记得是> 1023
    • OK 任何其他应用程序正在使用您选择的端口的可能性非常低。但无论如何我都会有一种不好的感觉。
    【解决方案4】:

    有多种方法可以实现这一目标。在 Java 中,你可以使用 JMS 来做这样的事情。如果您使用的是 Spring,则有此模板。 这是关于如何开始使用 JMS 的tutorial

    或者你可以使用Sockets,甚至RMI在多个进程之间交换数据。

    【讨论】:

    • 嗨,Alex,我快速浏览了 JSM 框架,它似乎是一个成熟的企业级消息传递框架,对于像这样的简单任务来说似乎有点过头了?你有什么想法?至于 RMI,它看起来不错,但似乎我需要在后台运行一个单独的 RMI 服务来处理服务器和客户端之间的通信。到目前为止,使用简单的套接字似乎是最好的、轻量级的想法。
    【解决方案5】:

    您需要执行某种进程间通信。有许多技术可以用来实现这一目标,包括:

    • 套接字
    • 网络服务
    • Java 远程方法调用 (RMI)
    • 使用数据库
    • 写入文件

    (写入文件对于 IPC 来说是一个糟糕的选择,除非您使用的是 POSIX 命名管道而不是普通文件)。

    【讨论】:

      【解决方案6】:

      另一种选择是使用在单独进程中运行的缓存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        • 2011-05-02
        • 2019-04-14
        • 2023-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多