Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GUI Halt when starting server using ServerSocket

I'm trying to create a simple Chat program, I found all kinds of example but yet I do try to accomplish it from scratch.

I have Server class (extends thread) and a GUI class, when either Connect or Disconnect buttons are clicked the GUI is halted (stuck)

Server code:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author Shahar Galukman
 */
public class ChatServer extends Thread{

    ServerSocket ss;
    boolean serverStopped = false;
    private int port = 18524;

    public ChatServer(){
        serverStart();
    }

    private void serverStart(){
        //Create new server socket
        try {
            ss = new ServerSocket(port);
        } catch (Exception e) {
            System.out.println("An error eccurd connection server: " + e.getMessage());
        }
        //wait for clients to connect
        while(!serverStopped){
            try {
                Socket clientSocket = ss.accept();
                /*
                 * Code will halt here until a client socket will be accepted.
                 * Below a new client thread will be created
                 * enabling multi client handling by the server
                */

                //create new ChatClientThread here

            } catch (IOException ex) {
                System.out.println("Error accpeting client socket");
            }
        }
    }
    //Stop the server
    public void stopServer(){
        serverStopped = true;
        ss = null;
    }

}

And i have a simple SWING GUI having connect and disconnect buttons, I'm using a inside class called Handler to add action listener to the bottons.

Handler class (located in the end of the GUI class:

//inner class
    class Handler implements ActionListener
    {
        //This is triggered whenever the user clicks the login button
            @Override
        public void actionPerformed(ActionEvent ae)
        {
            ChatServer server = new ChatServer();
            //checks if the button clicked
            if(ae.getSource()== connectButton)
            {
                try{
                    server.start();
                    serverStatusField.setText("Connected");
                }catch(Exception e){
                    e.printStackTrace();
                }
            }else if(ae.getSource()== disconnectButton){
                server.stopServer();
                serverStatusField.setText("Disconnected");
            }
        }
    }

Also in the GUI class I'm adding the action listener to the bottuns as follows:

public GUI() {
        initComponents();
        //create new handler instance
        handle = new Handler();
        connectButton.addActionListener(handle);
        disconnectButton.addActionListener(handle);
    }

When I click on the connect bottun a new Server thread is starting, as far as I understand. so why is the GUI get stuck? Should I use multi threading here?

like image 251
Shahar Galukman Avatar asked Apr 30 '26 04:04

Shahar Galukman


1 Answers

In your serverStart method, you have a sort of infinite loop which waits for the server to stop. When this button is called, the caller thread while certainly loop forever and block other calls.

In Swing, GUI is handled by the main thread. So if you call serverStart from the main thread, the gui will block until the loop is broken which will never happen.

Therefore, yes you should use mutithreading and call serverStart on another independant thread.

Normally, you should go for the following solution:

  1. Thread for GUI calls (dynamic gui handling ...)
  2. Thread(s) for heavy backend work (Socket connections, Data loading ..)

EDIT:

Here's a nice oracle tutorial about thread:

http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

2nd EDIT:

There is also something wrong in your code. Why is the method serverStart called in the constructor of ChatServer and not on the run method overriden from Thread? In that case, the infinite loop is called on the main thread when the ChatServer thread is constructed. I think you should call the serverStartin the run method of Thread:

ex:

public class ChatServer extends Thread{
    ....
    public ChatServer(){
    }

    @Override 
    public void run {
        serverStart();
    }
like image 160
Adel Boutros Avatar answered May 01 '26 20:05

Adel Boutros



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!