所以我正在创建一个应用程序,当我按下开始按钮时启动服务器。我是Java的新网络,所以服务器非常基础。当我尝试启动服务器时,应用程序冻结。我知道我必须使用多线程来解决它,但我不知道如何多线程。以下是启动按钮事件的一小段代码片段:
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == startButton) {
appendToChat("CONSOLE > Trying to start server...");
server = new Server(4454);
inputField.setEditable(true);
stopButton.setEnabled(true);
startButton.setEnabled(false);
}
以下是服务器的代码:
public class Server {
private ServerSocket serverSocket;
private Socket socket;
private Scanner scanner;
private PrintStream stream;
private int port;
private boolean succes = false;
public Server(int port) {
this.port = port;
init();
}
public void sendToClient(String value) {
stream.println(value);
}
public String getMessage() {
if(scanner == null) {
return "reader NullPointerException";
}
return scanner.nextLine();
}
public int getPort() {
return port;
}
public void stop() {
try {
serverSocket.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
scanner.close();
stream.close();
}
public boolean isSucces() {
return succes;
}
private void init() {
try {
serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
scanner = new Scanner(socket.getInputStream());
stream = new PrintStream(socket.getOutputStream());
succes = true;
} catch (Exception e) {
succes = false;
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
您的问题是您在调用ServerSocket.accept()时阻止了UI线程。您需要在单独的线程上调用它,以便UI线程可以继续其操作。
将init()方法代码更改为内部Runnable类,并在init()
中运行private void init() {
new Thread(new SocketRunner()).start();
}
private class SocketRunner implements Runnabled {
public void run() {
try {
serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
scanner = new Scanner(socket.getInputStream());
stream = new PrintStream(socket.getOutputStream());
succes = true;
} catch (Exception e) {
succes = false;
e.printStackTrace();
}
}
}
答案 1 :(得分:0)
应用程序冻结,因为serverSocket.accept()
正在等待4454端口中的请求。所以你必须在不同的线程中启动你的服务器。代码更新。
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == startButton) {
appendToChat("CONSOLE > Trying to start server...");
new Thread(new Runnable() {
@Override
public void run() {
server = new Server(4454);
}
}).start();
inputField.setEditable(true);
stopButton.setEnabled(true);
startButton.setEnabled(false);
}
答案 2 :(得分:0)
您的程序正在冻结,因为如果有任何客户端可以接受,服务器就会开始监听。我建议您的Server
课程延长Thread
。您需要实现run()
函数,该函数应包含init()
方法和带getMessage()
函数的无限循环。创建Server
对象后,您必须调用start()
方法。
public class Server extends Thread {
private ServerSocket serverSocket;
private Socket socket;
private Scanner scanner;
private PrintStream stream;
private int port;
private boolean succes = false;
public Server(int port) {
this.port = port;
}
@Override
public void run() {
init();
while(true) {
getMessage();
}
}
public void sendToClient(String value) {
stream.println(value);
}
public String getMessage() {
if(scanner == null) {
return "reader NullPointerException";
}
return scanner.nextLine();
}
public int getPort() {
return port;
}
public void disconnect() {
try {
serverSocket.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
scanner.close();
stream.close();
}
public boolean isSucces() {
return succes;
}
private void init() {
try {
serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
scanner = new Scanner(socket.getInputStream());
stream = new PrintStream(socket.getOutputStream());
succes = true;
} catch (Exception e) {
succes = false;
e.printStackTrace();
}
}
}
actionPerformed()
函数:
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == startButton) {
appendToChat("CONSOLE > Trying to start server...");
server = new Server(4454);
server.start();
inputField.setEditable(true);
stopButton.setEnabled(true);
startButton.setEnabled(false);
}