gpt4 book ai didi

java - 使用 ServerSocket 启动服务器时 GUI 暂停

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:18:19 25 4
gpt4 key购买 nike

我正在尝试创建一个简单的聊天程序,我找到了各种示例,但我还是尝试从头开始完成它。

我有服务器类(扩展线程)和一个 GUI 类,当单击“连接”或“断开连接”按钮时,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 的内部类来向按钮添加 Action 监听器。

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 类中,我将 Action 监听器添加到 bottun,如下所示:

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

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

最佳答案

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

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

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

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

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

编辑:

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

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

第二次编辑:

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

例如:

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

@Override
public void run {
serverStart();
}

关于java - 使用 ServerSocket 启动服务器时 GUI 暂停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16263351/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com