【问题标题】:Java Threads - Getting ServerSocket input to update SwingJava 线程 - 获取 ServerSocket 输入以更新 Swing
【发布时间】:2012-05-14 20:14:03
【问题描述】:

我首先问了this 的问题,我了解了 EDT 的工作原理,并通过阅读this 开始阅读更多关于 Swing 和工作线程的信息。我开始了解它们是如何工作的,并将我的代码固定在它将运行的位置。现在我正在尝试从我的工作线程 (服务器) 获取信息来更新我的 GUI。尽管我似乎无法解决问题,但我遇到了问题。问题是我需要继续监听新客户端(因为服务器应该处理多个客户端),但因为那是在一个 while 循环中,我从来没有遇到我的工作线程的返回。我也看不到任何其他设置方式。有人可以看看我的代码并提出一种我可以让它工作的方法吗?

Main.class

package com.sever.core;

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;

import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Main { 

private SocketManager network;
private Window window;

public static void main(String[] args){         
    Main main = new Main();
    main.runGUI();
    main.runServer();
}

private void runGUI(){

    //Runs the swing components in the EDT.
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
            window = new Window();
            window.setVisible(true);
        }       
    });
}

private void runServer(){

    //Runs the Server process on a worker thread.
    SwingWorker<String, String> server = new SwingWorker(){
        @Override
        protected Object doInBackground() throws Exception {    
            network = new SocketManager(25595);
            /*
             * Here is the problem. I need to keep running this code so,
             * that I can let multiple clients connect. However,
             * it then never reaches the return.
             */
            while(true){
                try {   
                    network.setSocket(network.getServerSocket().accept());
                    addUser(network.getSocket());
                } catch (Exception e) {
                    System.out.println("Failed to connect.");
                }
            }
            return network.getMessage(); 
        }

        @Override
        protected void done(){
            try {
                window.updateChat(get().toString());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    };
    server.run();
}

private void addUser(Socket s){
    try {
        Scanner input = new Scanner(s.getInputStream());
        network.addUser(input.nextLine());
    } catch (Exception e) {

    }
}
}

【问题讨论】:

  • 您不需要为您的服务器使用 SwingWorker,因为永远不会从 EDT 调用“runServer()”方法。因此它从未在 EDT 上启动,因此您不必从 EDT 上运行它。
  • @JasperSiepkes 在我的“runServer()”方法中我使用 ServerSocket 方法 accept(),它将尝试在 EDT 上运行。 'network.setSocket(network.getServerSocket.accept())'
  • 为什么要在 EDT 上运行套接字接受器?基本上,套接字接受器应该在普通线程上运行并在 EDT 上触发事件(如果需要),但整个事情应该在普通线程上运行,而不是 EDT。您可以从任何其他线程使用“SwingUtilities.invokeLater()”方法。您不需要从 SwingWorker 执行此操作。
  • @JasperSiepkes 我被引导相信套接字 accept() 方法,因为它不断等待,默认情况下在 EDT 上运行。当我在工作线程中没有它时,我的程序冻结了,因为 swing 和 accept() 方法都在 EDT 上,所以我不得不将 accept() 方法移动到工作线程。这是我在link here上被告知要这样做的问题
  • 默认情况下,EDT 上没有运行任何内容;它在标准线程上运行。您可以使用“SwingUtilities.invokeLater()”安排在 EDT 上执行的任务。 EDT 是所有 Swing 魔术必须发生的地方。 SwingWorkers 用于轻松“脱离”EDT。但是,您可以为此目的使用任何线程。 SwingWorkers 非常方便,因为它们具有在 EDT 上自动执行的回调方法以及其他一些使它们易于与 Swing 一起使用的魔法。为了让这一切更容易理解,您需要将服务器和客户端分离到单独的应用程序中。

标签: java multithreading swing sockets client-server


【解决方案1】:

来自Java Tutorials

服务器

public class Server {

    public static void main(String[] args) {
        ServerSocket server = new ServerSocket(4444);

        while(true) {
            new ServerThread(server.accept()).start();
        }
    }
}

服务器线程

public class ServerThread implements Runnable {

    private InputStream in;
    private OutputStream out;

    public ServerThread(Socket client) {
        in = client.getInputStream();
        out = client.getOutputStream();
    }

    public void run() {
        // do your socket things 
    }
}

【讨论】:

    猜你喜欢
    • 2012-05-21
    • 2023-03-11
    • 2013-04-29
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多