0

I want to run a java server program in my ubuntu computer through terminal but the problem is that once I start the program I can not stop it (the program is running in the terminal and waiting for the client).

This is my code:

import java.net.*; 
import java.io.*; 

public class EchoServer2 extends Thread {
    protected Socket clientSocket;

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;

        try {
            serverSocket = new ServerSocket(2000);
            System.out.println("Connection Socket Created");
            try {
                while (true) {
                    System.out.println("Waiting for Connection");
                    new EchoServer2(serverSocket.accept());
                }
            } catch (IOException e) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
        } catch (IOException e) {
            System.err.println("Could not listen on port: 2000.");
            System.exit(1);
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.err.println("Could not close port: 2000.");
                System.exit(1);
            }
        }
    }

    private EchoServer2(Socket clientSoc) {
        clientSocket = clientSoc;
        start();
    }

    public void run() {
        System.out.println("New Communication Thread Started");

        try {
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
                    true);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));

            String inputLine;

            while ((inputLine = in.readLine()) != null) {
                System.out.println("Server: " + inputLine);
                out.println(inputLine);

                if (inputLine.equals("Bye."))
                    break;
            }

            out.close();
            in.close();
            clientSocket.close();
        } catch (IOException e) {
            System.err.println("Problem with Communication Server");
            System.exit(1);
        }
    }
}

I know that I can kill the process but I don't want to stop the program forcefully. I want to know: how can I stop the program safely? How can I implement this in my code?

bcsb1001
  • 2,834
  • 3
  • 24
  • 35
A Panda
  • 13
  • 1
  • 1
  • 3

3 Answers3

1

You can hit the Ctrl + C keys and it will send a SIGINT (interrupt) to your program. If you don't have specific logic to run at the program shutdown it'd probably do the job.

If you have some logic to run at program shutdown, check this answer.

Community
  • 1
  • 1
Just1602
  • 41
  • 5
  • This, of-course, kills the process; something the OP doesn't want. – Mordechai Jun 15 '16 at 19:05
  • SIGINT (interrupt) is different from SIGKILL which kill de process. Otherwise, the solution is still to catch the signal and exit the program. – Just1602 Jun 15 '16 at 19:09
1

Let's get it clear, you block the main thread at client acception. It will be no real way to cleanly close the program.

My solution would be to run a separate thread, that will do the acception job.

To illustrate, here's my code:


This is the acception thread:

private static Thread acception = new Thread("Acception Thread") {

    public void run() {

        try {
            while (true) {
                System.out.println("Waiting for Connection");
                new EchoServer2(serverSocket.accept());
            }
    ->  } catch (SocketException e) {
    ->      if(serverSocket.isClosed())
    ->          System.out.println("Connection Closed.");
    ->  }
        } catch (IOException e) {
            System.err.println("Accept failed.");
            System.exit(1);
        }

    }
};

Here's the modified main method:

public static void main(String[] args) throws IOException {
    ServerSocket serverSocket = null;


    try {
        serverSocket = new ServerSocket(2000);
        System.out.println("Connection Socket Created");
->      acception.start();
    } catch (IOException e) {
        System.err.println("Could not listen on port: 2000.");
        System.exit(1);
    }


    //support to close, using the command line.

    Scanner scn = new Scanner(System.in);
    String s = scn.next();

    while(true) {
        if("quit".equals.(s)) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.err.println("Could not close port: 2000.");
                System.exit(1);
            } finally {
                break;
            }
        }
        s = scn.next();
    }
}
Mordechai
  • 15,437
  • 2
  • 41
  • 82
0

Check this link http://www.oracle.com/technetwork/java/javase/signals-139944.html Should help you

Edit: Solution 1: Add this to your main method

Runtime.getRuntime().addShutdownHook(new Thread() {
   public void run() {
       System.out.println("Prepare to exit");
       //some cleaning up code...
   }
});

Solution 2: Add another thread which waits for "exit" command, SOmething like:

    new Thread() {
        @Override
        public void run() {
            System.out.println("Type exit to exit;-)");
            Console c = System.console();
            String msg = c.readLine();
            if (msg.equals("exit")) {
                //some cleaning up code...
                System.exit(0);                 
            }
        }
    }.start();
Planck Constant
  • 1,406
  • 1
  • 17
  • 19