3

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?

4

1 回答 1

4

在您的serverStart方法中,您有一种等待服务器停止的无限循环。当这个按钮被调用时,调用者线程 while 肯定会永远循环并阻塞其他调用。

在 Swing 中,GUI 由主线程处理。因此,如果您serverStart从主线程调用,gui 将阻塞,直到循环被打破,这永远不会发生。

因此,是的,您应该使用多线程并调用serverStart另一个独立线程。

通常,您应该采用以下解决方案:

  1. GUI 调用线程(动态 gui 处理 ...)
  2. 用于繁重后端工作的线程(套接字连接、数据加载..)

编辑:

这是一个关于线程的不错的 oracle 教程:

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

第二次编辑:

你的代码也有问题。为什么serverStart在构造函数中调用方法ChatServer而不是在run从 Thread 覆盖的方法上?在这种情况下,在构造 ChatServer 线程时会在主线程上调用无限循环。我认为你应该serverStart在 Thread 的 run 方法中调用:

前任:

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

    @Override 
    public void run {
        serverStart();
    }
于 2013-04-28T13:34:26.630 回答