在运行我正在研究的小型战舰计划时,我目前遇到一些问题。我有两个GUI,一个用于服务器,一个用于客户端。当我单击“启动服务器” jButton时,程序将冻结,直到从客户端接收到某些信息为止。
GUI的图像(如果有帮助的话):
我没有任何问题可以通过启动客户端程序来解冻,我的问题是,如何制作它以便它在等待时不会冻结?非常感谢。
package battleship;
import javax.swing.JOptionPane;
import java.io.IOException;
import java.util.Scanner;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
/**
*
* @author ftonye
*/
public class BackGroundCom implements Runnable {
private int port;
private ServerSocket ss;
private Socket cs;
private Scanner reader;
private PrintStream writer;
public int missileIncomming;
public int missileOutgoing;
public Boolean dataToSend;
InetAddress sa = null;
public BackGroundCom(int port) {
this.port = port;
dataToSend = true;
missileOutgoing = 100;
startServer();
}
private void startServer() {
try {
sa = InetAddress.getLocalHost();
System.out.println(sa);
} catch (UnknownHostException ex) {
Logger.getLogger(BackGroundCom.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Server started");
try {
ss = new ServerSocket(this.port);
cs = ss.accept();
JOptionPane.showMessageDialog(null, "Server accept connection from" + cs.getInetAddress().getHostAddress());
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
}
System.out.println("Server accept connection");
}
我的BattleSea.java的一部分,在它冻结之前,我在其中单击按钮:
btnStartServer = new JButton("Start Server");
btnStartServer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
com = new BackGroundCom(Integer.parseInt(txtPortNumber.getText().toString()));
t = new Thread(com);
t.start();
}
});
我正在尝试了解如何使其永不冻结。谢谢
答案 0 :(得分:2)
我希望呼叫cs = ss.accept();
处于阻塞状态。这将阻塞,直到客户端连接到服务器。您运行此命令是为了响应按下按钮,因为在按钮操作代码中,您构造了BackGroundCom
,并且该对象的构造函数调用了startServer
,该对象直接执行了此accept()
行。>
似乎您正在尝试设置BackGroundCom
对象,以使其在后台线程中发生,但是我首先描述的是在创建和运行线程之前发生的。也许您想要做的就是将startServer
调用移到run()
对象的BackGroundCom
方法中。尽管它实现了run()
,但在BackGroundCom
中没有看到Runnable
方法。我认为它在代码中更进一步。没有它,该代码甚至无法编译。
答案 1 :(得分:0)
Steve是正确的。 ServerSocket.accept();
方法将阻塞,直到建立连接为止。您必须将其放在另一个Thread
中,以免阻塞EDT(Event Dispatching Thread)
。 EDT是您的GUI运行的地方。
public BackGroundCom(int port) {
this.port = port;
dataToSend = true;
missileOutgoing = 100;
new Thread(() -> (startServer()).start(); // run in new thread
}