5

I'm making a client-server application, in which the user can turn on or switch off the server from a gui; in order to let it work, I use a SwingWorker nested class. All seems to work correctly, but when I switch off the server and re-turn it on it doesn't work, probably because there is still another instance open of it that can't be overwritten: server is blocked on the accept() method. I want to kill the previous instance when the user presses the switch off button, but I don't know how.

Here's the SwingWorker class that gives me problems:

class SwingWorkGUI extends SwingWorker
    {
        @Override
        protected Integer doInBackground() throws Exception {
            int delay = 1000; 
            final Timer time = new Timer(delay, null);
            time.addActionListener( new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (Server.up == true){
                        upTimeMillis += 1000;
                        long diff = upTimeMillis/1000;
                        long numHrs = diff/60;
                        diff = diff%60;
                        long numMins = diff/60;
                        long numSecs = diff%60;
                        upTime.setText(numHrs + ":" + numMins + ":" + numSecs);
                    }
                    else {
                        upTime.setText("Server Actually Down");
                        time.stop();
                    }
                }           
            });
            time.start();
            mainServer = new Server();
            return null;
        }
    }

Everytime the Turn On button is pressed, the actionPerformed determines whether the server is already on or not, then if not runs

SwingWorkGUI swg = new SwingWorkGUI(); 
swg.execute();

The execution blocks in the following instruction, but only the second (third,ecc.) time it is called:

mainServer = new Server();

Server.up is a static variable that helps me to kill the while(true) method in server.

How can I kill the open instance without closing all the application?

tenik
  • 250
  • 1
  • 4
  • 20
  • If you're running the server on a separate thread you can store a reference to that thread and call `interrupt()` on it and then clean up the reference to the server. This should cause the server to quit whatever it is doing. (You will probably also want to catch `InterruptedException`s on the `Server` and do some internal clean up as necessary). – SamYonnou May 27 '13 at 15:43
  • Call `socket.close()` from an external thread to interrupt the `socket.accept()` method and then shutdown your server: http://stackoverflow.com/questions/2983835/how-can-i-interrupt-a-serversocket-accept-method – DannyMo May 27 '13 at 21:01

1 Answers1

0

If I understand correctly your problem is that the ServerSocket object is blocked on the accept() call and you need to unblock it. Some options:

  1. Call ss.close() from another thread (assumes ss is your ServerSocket object). This will make accept() throw a SocketException. Reference: Javadocs for ServerSocket.close()

  2. Create a new Socket from another thread and connect to your own server. This will unblock the accept() call. Now you can check your Server.up flag.

  3. Set a timeout on your ServerSocket, e.g. 5 seconds. This will make accept() throw an InterruptedIOException on timeout. Reference: Javadocs for SO_TIMEOUT

Grodriguez
  • 21,501
  • 10
  • 63
  • 107