I am trying to create a program with Java that can only have one instance of it running at a time. I am using Sockets and ServerSockets to try to achieve this.
How the program is supposed to work is:
The main method will check if any parameters have been passed, it will try to write the first parameter to the server, if it fails that means, that means that this is the only running instance, so it will open the ServerSocket and then start the frame. If it doesn't fail then the application is already running so it should send the string and the other instance should be able to read it and process it.
Here's the main method:
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();
}
}
And here's the server class:
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) {
}
}
}
Although half of this code works (only one instance runs at a time), only the first set of data are being passed and then the program stops reading. How can I make the socket listen until the program is closed?
I your checkInput() method, you are accepting for client connection once here. Try something like this:
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();
}
As soon as another instance it started, server will accept the request, do the processing and then again starts waiting for more requests (for this we called cehckInput again).
Also in your main() add this:
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.
}
On upon termination of program, your sockets will auto close. Also if you want to explicitly close the sockets, you can add a shutdown hook to close it. A simple hook looks like this.
Runtime.getRuntime().addShutdownHook(your thread that will close sockets);