在等待客户端答复时冻结了GUI

时间:2019-04-27 17:36:56

标签: java

在运行我正在研究的小型战舰计划时,我目前遇到一些问题。我有两个GUI,一个用于服务器,一个用于客户端。当我单击“启动服务器” jButton时,程序将冻结,直到从客户端接收到某些信息为止。

GUI的图像(如果有帮助的话):

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();


            }

        });

我正在尝试了解如何使其永不冻结。谢谢

2 个答案:

答案 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
}