GUI使用ServerSocket启动服务器时停止

时间:2013-04-28 13:29:04

标签: java swing netbeans-7 actionlistener

我正在尝试创建一个简单的聊天程序,我找到了各种各样的例子,但我确实尝试从头开始。

我有Server类(扩展线程)和GUI类,当单击Connect或Disconnect按钮时GUI停止(卡住)

服务器代码:

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;
    }

}

我有一个简单的SWING GUI,它有连接和断开按钮,我正在使用一个叫做Handler的内部类来为Bottons添加动作监听器。

Handler类(位于GUI类的末尾:

//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");
            }
        }
    }

同样在GUI类中,我将动作监听器添加到bottuns,如下所示:

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

当我点击连接bottun时,据我所知,新的服务器线程正在启​​动。那么为什么GUI会卡住?我应该在这里使用多线程吗?

1 个答案:

答案 0 :(得分:4)

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

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

因此,是的,你应该使用mutithreading并在另一个独立的线程上调用serverStart

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

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

    这是关于线程的一个很好的oracle教程:

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

    第二次编辑:

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

    例如:

    public class ChatServer extends Thread{
        ....
        public ChatServer(){
        }
    
        @Override 
        public void run {
            serverStart();
        }