为了账号安全,请及时绑定邮箱和手机立即绑定

GUI 在等待来自客户端的答复时冻结

GUI 在等待来自客户端的答复时冻结

慕虎7371278 2022-10-26 16:49:30
我目前在运行我正在研究的这个小型战舰程序时遇到了一些问题。我有两个 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");    }我试图了解如何让它永远不会冻结。谢谢
查看完整描述

2 回答

?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

我希望这cs = ss.accept();是阻塞的呼叫。这将一直阻塞,直到客户端连接到服务器。您在按下按钮时运行它,因为在您的按钮操作代码中,您构造了 a BackGroundCom,并且该对象的构造函数调用startServer,它直接执行此accept()行。

似乎您正在尝试设置BackGroundCom对象,以便它在后台线程中发生的事情,但我上面所描述的一切都发生在您创建和运行线程之前。也许您想要做的是将startServer调用移动到对象的run()方法中BackGroundCom。我没有在 中看到run()方法BackGroundCom,尽管它实现了Runnable. 我认为它在代码中更进一步。没有它,这段代码甚至无法编译。


查看完整回答
反对 回复 2022-10-26
?
手掌心

TA贡献1942条经验 获得超3个赞

史蒂夫是对的。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

}


查看完整回答
反对 回复 2022-10-26
  • 2 回答
  • 0 关注
  • 71 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信