从swing中的事件处理程序启动服务器

时间:2016-09-26 19:15:10

标签: java multithreading swing server event-handling

所以我正在创建一个应用程序,当我按下开始按钮时启动服务器。我是Java的新网络,所以服务器非常基础。当我尝试启动服务器时,应用程序冻结。我知道我必须使用多线程来解决它,但我不知道如何多线程。以下是启动按钮事件的一小段代码片段:

        @Override
        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == startButton) {

                appendToChat("CONSOLE > Trying to start server...");
                server = new Server(4454);

                inputField.setEditable(true);
                stopButton.setEnabled(true);
                startButton.setEnabled(false);
            }

以下是服务器的代码:

public class Server {

private ServerSocket serverSocket;
private Socket socket;
private Scanner scanner;
private PrintStream stream;

private int port;

private boolean succes = false;

public Server(int port) {
    this.port = port;   
    init();
}

public void sendToClient(String value) {
    stream.println(value);
}

public String getMessage() {
    if(scanner == null) {
        return "reader NullPointerException";
    }
    return scanner.nextLine();
}

public int getPort() {
    return port;
}

public void stop() {
    try {
        serverSocket.close();
        socket.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    scanner.close();
    stream.close();
}

public boolean isSucces() {
    return succes;
}

private void init() {
    try {
        serverSocket = new ServerSocket(port);
        socket = serverSocket.accept();
        scanner = new Scanner(socket.getInputStream());
        stream = new PrintStream(socket.getOutputStream());
        succes = true;
    } catch (Exception e) {
        succes = false;
        e.printStackTrace();
    }

}

 }

3 个答案:

答案 0 :(得分:2)

您的问题是您在调用ServerSocket.accept()时阻止了UI线程。您需要在单独的线程上调用它,以便UI线程可以继续其操作。

将init()方法代码更改为内部Runnable类,并在init()

中运行
private void init() {
  new Thread(new SocketRunner()).start();
}

private class SocketRunner implements Runnabled {
    public void run() {
      try {
        serverSocket = new ServerSocket(port);
        socket = serverSocket.accept();
        scanner = new Scanner(socket.getInputStream());
        stream = new PrintStream(socket.getOutputStream());
        succes = true;
      } catch (Exception e) {
        succes = false;
        e.printStackTrace();
      }
    }
}

答案 1 :(得分:0)

应用程序冻结,因为serverSocket.accept()正在等待4454端口中的请求。所以你必须在不同的线程中启动你的服务器。代码更新。

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == startButton) {

            appendToChat("CONSOLE > Trying to start server...");

            new Thread(new Runnable() {
                @Override
                public void run() {
                    server = new Server(4454);
                }
            }).start();


            inputField.setEditable(true);
            stopButton.setEnabled(true);
            startButton.setEnabled(false);
        }

答案 2 :(得分:0)

您的程序正在冻结,因为如果有任何客户端可以接受,服务器就会开始监听。我建议您的Server课程延长Thread。您需要实现run()函数,该函数应包含init()方法和带getMessage()函数的无限循环。创建Server对象后,您必须调用start()方法。

public class Server extends Thread {

    private ServerSocket serverSocket;
    private Socket socket;
    private Scanner scanner;
    private PrintStream stream;

    private int port;

    private boolean succes = false;

    public Server(int port) {
        this.port = port;   
    }

    @Override
    public void run() {
        init();
        while(true) {
            getMessage();
        }
    }

    public void sendToClient(String value) {
        stream.println(value);
    }

    public String getMessage() {
        if(scanner == null) {
            return "reader NullPointerException";
        }
        return scanner.nextLine();
    }

    public int getPort() {
        return port;
    }

    public void disconnect() {
        try {
            serverSocket.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        scanner.close();
        stream.close();
    }

    public boolean isSucces() {
        return succes;
    }

    private void init() {
        try {
            serverSocket = new ServerSocket(port);
            socket = serverSocket.accept();
            scanner = new Scanner(socket.getInputStream());
            stream = new PrintStream(socket.getOutputStream());
            succes = true;
        } catch (Exception e) {
            succes = false;
            e.printStackTrace();
        }
    }
}

actionPerformed()函数:

 @Override
 public void actionPerformed(ActionEvent e) {
    if(e.getSource() == startButton) {

        appendToChat("CONSOLE > Trying to start server...");
        server = new Server(4454);
        server.start();

        inputField.setEditable(true);
        stopButton.setEnabled(true);
        startButton.setEnabled(false);
    }