我正在尝试创建一个简单的聊天程序,我找到了各种各样的例子,但我确实尝试从头开始。
我有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会卡住?我应该在这里使用多线程吗?
答案 0 :(得分:4)
在serverStart
方法中,您有一种等待服务器停止的无限循环。当调用此按钮时,调用者线程肯定会永远循环并阻止其他调用。
在Swing中,GUI由主线程处理。因此,如果从主线程调用serverStart
,gui将会阻塞,直到循环中断,这将永远不会发生。
因此,是的,你应该使用mutithreading并在另一个独立的线程上调用serverStart
。
通常,您应该采用以下解决方案:
修改强>
这是关于线程的一个很好的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();
}