猿问

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

我目前在运行我正在研究的这个小型战舰程序时遇到了一些问题。我有两个 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");


    }

我试图了解如何让它永远不会冻结。谢谢


慕虎7371278
浏览 72回答 2
2回答

慕婉清6462132

我希望这cs = ss.accept();是阻塞的呼叫。这将一直阻塞,直到客户端连接到服务器。您在按下按钮时运行它,因为在您的按钮操作代码中,您构造了 a BackGroundCom,并且该对象的构造函数调用startServer,它直接执行此accept()行。似乎您正在尝试设置BackGroundCom对象,以便它在后台线程中发生的事情,但我上面所描述的一切都发生在您创建和运行线程之前。也许您想要做的是将startServer调用移动到对象的run()方法中BackGroundCom。我没有在 中看到run()方法BackGroundCom,尽管它实现了Runnable. 我认为它在代码中更进一步。没有它,这段代码甚至无法编译。

手掌心

史蒂夫是对的。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}
随时随地看视频慕课网APP

相关分类

Java
我要回答