Java: как я могу создать приложение, которое будет запускаться только в том случае, если его экземпляр не существует, и вызывать экземпляр, если он существует?

Я пытаюсь создать программу с Java, которая может одновременно запускать только один экземпляр. Я использую Sockets и ServerSockets, чтобы попытаться добиться этого.

Как программа должна работать:

Основной метод проверит, были ли переданы какие-либо параметры, он попытается записать первый параметр на сервер, если это не удастся, это означает, что это единственный запущенный экземпляр, поэтому он откроет ServerSocket, а затем запустит Рамка. Если это не сработает, то приложение уже запущено, поэтому оно должно отправить строку, а другой экземпляр должен иметь возможность прочитать и обработать ее.

Вот основной метод:

public static void main(String[] args) {
    String fileName = null;
    if (args.length >= 1) {
        fileName = args[0];
    }
    if (Singleton.sendSignal(fileName)) {
        Frame.getFrame().open(fileName);
        Singleton.checkInput();
    }
}

И вот класс сервера:

public class Singleton {
    private static final int portNumber = 4243;
    private static ServerSocket serverSocket;
    private static Socket clientSocket;
    private static Socket echoSocket;

    public static boolean sendSignal() {
        try {
            echoSocket = new Socket(InetAddress.getLocalHost().getHostName(), portNumber);
            PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
            out.write("Open\n");
            out.close();
            close();
            return false;
        } catch (Exception e) {
            close();
            return true;
        }
    }

    public static void checkInput() {
        try {
            renewReader();
        } catch (Exception e) {
            close();
        }
    }

    public static void renewReader() throws Exception {
        serverSocket = new ServerSocket(portNumber);
        clientSocket = serverSocket.accept();
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String inputLine = in.readLine();
        if (inputLine.equals("Open")) {
            Widget.getInstance().setVisible(true);
        }
        close();
        renewReader();
    }

    public static void close() {
        try {
            serverSocket.close();
        } catch (Exception e) {
        }
        try {
            clientSocket.close();
        } catch (Exception e) {
        }
        try {
            echoSocket.close();
        } catch (Exception e) {
        }
    }

}

Хотя половина этого кода работает (одновременно выполняется только один экземпляр), передается только первый набор данных, а затем программа прекращает чтение. Как я могу заставить сокет слушать, пока программа не будет закрыта?


person nick zoum    schedule 01.10.2016    source источник


Ответы (1)


I ваш метод checkInput(), который вы принимаете для клиентского подключения один раз здесь. Попробуйте что-то вроде этого:

public static void checkInput() 
{   
     //do something here
     serverSocket = new ServerSocket(portNumber);
     //wait for request from client.
     Socket clientSocket = serverSocket.accept();
     //
     // do your processing here

     // call checkInput method again.
     checkInput();
}

Как только запустится другой экземпляр, сервер примет запрос, выполнит обработку, а затем снова начнет ждать новых запросов (для этого мы снова вызвали cehckInput).

Также в вашем main() добавьте это:

public static void main(String[] args) 
{
    String fileName = null;
    if (args.length >= 1) {
        fileName = args[0];
    }
    if (Singleton.sendSignal(fileName)) 
    {
        Frame.getFrame().open(fileName);

        // start the server in a thread so that main method can continue on
        new Thread()
        {
           public void run()
           {
                Singleton.checkInput();
           }
        }.start();
    }

    // do your other tasks.
}

После завершения программы ваши сокеты автоматически закроются. Также, если вы хотите явно закрыть сокеты, вы можете добавить хук выключения, чтобы закрыть его. Простой крючок выглядит так.

Runtime.getRuntime().addShutdownHook(your thread that will close sockets);
person Rishabh Kumar    schedule 01.10.2016
comment
новая ветка нужна? программа отлично работает без доп. Я имею в виду, что ничего не приостановлено. - person nick zoum; 01.10.2016
comment
Я добавил поток на всякий случай, так как если вы добавите какой-либо новый код в свой метод main() после условия if, он не будет выполняться, поскольку метод checkInput() вызывается рекурсивно. Таким образом, было бы разумно добавить рекурсивный метод в поток на всякий случай. И да, вы можете игнорировать часть потока, если уверены, что после этого в main больше не будет строк кода. - person Rishabh Kumar; 01.10.2016