简体   繁体   English

使用用户界面(Swing)在Java上启动ServerSocket冻结

[英]Starting ServerSocket on Java with User Interface(Swing) Freezes

Good day, 美好的一天,

I have an infinite loop for a ServerSocket, working fine... The problem is when I try to start the ServerSocket with a button. 我有一个ServerSocket的无限循环,工作正常...问题是当我尝试使用按钮启动ServerSocket时。 My user interface "Freeze" don't move, anything, but the server is up and fine, here I have a ScreenShot : 我的用户界面“冻结”什么都没有动,但服务器正常运行,这里有一个ScreenShot

http://i.gyazo.com/15d331166dd3f651fc7bda4e3670be4d.png http://i.gyazo.com/15d331166dd3f651fc7bda4e3670be4d.png

When I press the button "Iniciar" means Start server, the User Interface Freezes (ServerSocket infinite loop). 当我按下按钮“ Iniciar”时,表示启动服务器,用户界面冻结(ServerSocket无限循环)。 I can't change my code because its working fine. 我无法更改我的代码,因为它可以正常工作。

    public static void iniciarServer() {

    try {
        appendString("\nServidor iniciado.");
        System.out.println("asdasd");
    } catch (BadLocationException e1) {
        e1.printStackTrace();
    }

    try {
        ss = new ServerSocket(1234, 3);
        while (true) {
            System.out.println("Esperando conexiones...");
            appendString("\nEsperando conexiones...");
            Socket s = ss.accept();
            System.out.println("Conexión entrante: " + s.getRemoteSocketAddress());
            appendString("\nConexión entrante: " + s.getRemoteSocketAddress());

            conexiones++;
            //System.out.println("Debug: conexiones SERVER: " + conexiones);
            MultiThread mt = new MultiThread(s, conexiones);
            mt.start();
            ///////////////////////////////////////////////////////////////
        }
    } catch (IOException e) {
        System.out.println("Error Server: " + e.getMessage());
    } catch (BadLocationException e) {
        e.printStackTrace();
    } 
    stopServer();
}

appendString(); appendString(); Is for add some text to the JTextPane, but doesnot work because the UI freezes. 用于向JTextPane添加一些文本,但由于UI冻结而无法正常工作。

Is there any way to do an user interface that don't freeze by the infinite loop? 有什么方法可以做一个不会被无限循环冻结的用户界面?

Thanks! 谢谢!

Swing is a single threaded framework, meaning any blocking or long running operation executed within the context of the Event Dispatching Thread will prevent it from processing the Event Queue, making your application hang. Swing是一个单线程框架,这意味着在事件调度线程的上下文中执行的任何阻止或长时间运行的操作都将阻止它处理事件队列,从而使应用程序挂起。

It's also not thread safe, so you should never try and modify the state of any UI component from out side of the EDT. 它也不是线程安全的,因此您永远不要尝试从EDT的外部修改任何UI组件的状态。

Take a look at Concurrency in Swing and Worker Threads and SwingWorker for more details 查看SwingWorker线程中的并发性 以及SwingWorker,以了解更多详细信息

public class ServerSocketWorker extends SwingWorker<Void, String> {

    private JTextArea ta;

    public ServerSocketWorker(JTextArea ta) {
        this.ta = ta;
    }

    @Override
    protected void process(List<String> chunks) {
        for (String text : chunks) {
            ta.append(text);
        }
    }

    @Override
    protected Void doInBackground() throws Exception {
        ss = new ServerSocket(1234, 3);
        while (true) {
            publish("\nEsperando conexiones...");
            Socket s = ss.accept();
            publish("\nConexión entrante: " + s.getRemoteSocketAddress());

            conexiones++;
            //System.out.println("Debug: conexiones SERVER: " + conexiones);
            MultiThread mt = new MultiThread(s, conexiones);
            mt.start();
            ///////////////////////////////////////////////////////////////
        }
    }

    @Override
    protected void done() {
        stopServer(); //??
    }
}

To start it, you could use something like... 要启动它,您可以使用类似...

public void iniciarServer() {
    ServerSocketWorker worker = new ServerSocketWorker(textAreaToAppendTo);
    worker.execute();
}

As an example 举个例子

The method ServerSocket.accept() is a blocking method. ServerSocket.accept()方法是一种阻塞方法。 This means that Socket s = ss.accept(); 这意味着Socket s = ss.accept(); stops the current thread until a connection to the server socket is opened. 停止当前线程,直到打开与服务器套接字的连接。

Event dispatching in Swing is single threaded, the while loop and the blocking operation mentioned above, will keep the thread 'busy' and block all other interactions with the UI. Swing中的事件调度是单线程的,上面提到的while循环和阻塞操作将使线程保持“繁忙”并阻塞与UI的所有其他交互。

You should run your entire while loop in a separate thread. 您应该在单独的线程中运行整个while循环。 When you want to stop the server, you should also ensure that the while loop is exited and the thread completes execution. 当您要停止服务器时,还应确保退出while循环,并且线程完成执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM