当命中JButton连接到服务器时,程序会冻结

我在java中使用TCP进行简单的1v1“私聊”。 目前,每当我使用JButtons时,我都会遇到问题。 这是我第一次尝试使用JButtons和ActionListeners,所以我不是100%肯定这里发生了什么。

我有两个单独的服务器和客户端项目。 要编译这些,它必须是两个单独的项目。

当我尝试按下按钮时出现问题A:启动服务器B:连接到服务器。

按钮冻结,就好像它处于推动状态一样。 在运行服务器并按下按钮时,要“取消”按钮,客户端必须尝试连接。 服务器向客户端发送MOTD,客户端应将其打印到文本窗口。 只有在服务器关闭后才打印出MOTD。 再次,不知道为什么

服务器代码:

package net.valid4life.chat; import java.awt.Component; public class Chat implements ActionListener { private static final long serialVersionUID = 1L; private static JFrame mainFrame; private static JPanel contentPane; private static JTextArea chatWindow; private static JTextArea serverWindow; private static JTextField chatBox; private static JTextField portBox; private static JLabel currentStatusL; private static JLabel portl; private static JLabel status; private static JButton startServerButton; private static int port = 1234; public static final int NOT_STARTED = 0; public static final int WAITING_FOR_CLIENT = 1; public static final int CONNECTED = 2; private static int currentStatus = NOT_STARTED; public static String newLine = "\n"; public static boolean started = false; static ServerSocket listener = null; public static void initGUI() { mainFrame = new JFrame("Chat Server"); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); mainFrame.setContentPane(contentPane); contentPane.setLayout(null); chatWindow = new JTextArea(); chatWindow.setLineWrap(true); chatWindow.setEditable(false); chatWindow.setBounds(220, 15, 200, 215); chatWindow.setAlignmentY(Component.BOTTOM_ALIGNMENT); contentPane.add(chatWindow); serverWindow = new JTextArea(); serverWindow.setLineWrap(true); serverWindow.setEditable(false); serverWindow.setBounds(10, 150, 201, 80); contentPane.add(serverWindow); chatBox = new JTextField(); chatBox.setBounds(221, 236, 199, 20); contentPane.add(chatBox); chatBox.setColumns(10); portBox = new JTextField("1234"); portBox.setBounds(68, 37, 86, 25); portBox.setActionCommand("portEnter"); portBox.setColumns(10); contentPane.add(portBox); portl = new JLabel("Port:"); portl.setFont(new Font("Times New Roman", Font.PLAIN, 16)); portl.setBounds(95, 20, 64, 14); contentPane.add(portl); status = new JLabel("Status:"); status.setFont(new Font("Times New Roman", Font.PLAIN, 16)); status.setBounds(15, 239, 46, 14); contentPane.add(status); currentStatusL = new JLabel(changeStatus(NOT_STARTED)); currentStatusL.setFont(new Font("Times New Roman", Font.PLAIN, 16)); currentStatusL.setBounds(60, 239, 151, 14); contentPane.add(currentStatusL); startServerButton = new JButton("Start Server"); startServerButton.setFont(new Font("Times New Roman", Font.PLAIN, 13)); startServerButton.setBounds(60, 96, 100, 40); startServerButton.setActionCommand("start"); startServerButton.addActionListener(new Chat()); contentPane.add(startServerButton); mainFrame.setVisible(true); } public static void main(String[] args) throws IOException { initGUI(); } public void actionPerformed(ActionEvent e) { if ("start".equals(e.getActionCommand())) { try { port = Integer.parseInt(portBox.getText()); startServerButton.setEnabled(false); listener = new ServerSocket(port); changeStatus(WAITING_FOR_CLIENT); serverWindow.append("The server has started on " + listener.getLocalPort()); } catch (IOException e1) { e1.printStackTrace(); } finally { try { startServer(); } catch (IOException e1) { e1.printStackTrace(); } } }else System.out.println("YOU BROKE IT"); } public static void startServer() throws IOException { try { System.out.println("Looking for client"); new ServerThread(listener.accept()).start(); System.out.println("Found client"); } catch (Exception e) { e.printStackTrace(); } finally { listener.close(); } } public static String changeStatus(int newStatus) { String newStatusText; switch (newStatus) { case 0: newStatusText = "Server not started."; break; case 1: newStatusText = "Waiting for client."; break; case 2: newStatusText = "Connected to client."; break; default: newStatusText = "Broken"; } currentStatus = newStatus; return newStatusText; } public static class ServerThread extends Thread { private Socket socket; public ServerThread(Socket socket) { this.socket = socket; Chat.serverWindow.append("New Connection from:" + socket.getInetAddress() + Chat.newLine); Chat.changeStatus(CONNECTED); } public void run() { try { BufferedReader in = new BufferedReader(new InputStreamReader( socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); out.println("MOTD:Welcome to the testing phase of this chat!"); out.println("To view commands simply type /help"); while (true) { String input = in.readLine(); if (input == null || input.equals(".")) { break; } out.println(input); } } catch (IOException e) { Chat.serverWindow.append("Error handling client"); } finally { try { socket.close(); } catch (IOException e) { Chat.serverWindow .append("Couldn't close a socket, what's going on?"); } Chat.serverWindow.append("Connection with client closed"); } } } } 

客户端代码:

  package net.valid4life.chat; import java.awt.Component; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; public class Chat implements ActionListener { private static JFrame mainFrame; private static JPanel contentPane; private static JTextArea chatWindow; private static JTextField chatBox; private static JTextField portBox; private static JLabel currentStatusL; private static JLabel portl; private static JLabel status; private static JButton connectButton; private static int port = 1234; private static String hostIP = "127.0.0.1"; public static final int NOT_STARTED = 0; public static final int WAITING_FOR_SERVER = 1; public static final int CONNECTED = 2; private static int currentStatus = NOT_STARTED; public static boolean serverStarted = false; private static JTextField IPField; private static JLabel IPL; private static BufferedReader in; private static PrintWriter out; public static void initGUI() { public static void connectToServer() throws Exception { port = Integer.parseInt(portBox.getText()); hostIP = IPField.getText(); Socket socket = new Socket("127.0.0.1", 1234); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); for (int i = 0; i < 3; i++) { chatWindow.append(in.readLine() + "\n"); } // connectButton.setEnabled(false); } public static void main(String[] args) throws Exception { initGUI(); connectToServer(); } public void actionPerformed(ActionEvent e) { if ("start".equals(e.getActionCommand())) { try { connectToServer(); } catch (Exception e1) { e1.printStackTrace(); } } else {System.out.println("ASDASD");} } public static String changeStatus(int newStatus) { String newStatusText; switch (newStatus) { case 0: newStatusText = "Server not started."; break; case 1: newStatusText = "Waiting for client."; break; case 2: newStatusText = "Connected to client."; break; default: newStatusText = "Broken"; } currentStatus = newStatus; return newStatusText; } } 

在此先感谢您的帮助!

您的服务器代码运行良好,但是当您调用connectToServer时,您的客户端阻止了事件调度线程。

Event Dispatching Thread负责处理重绘请求和新输入事件等。 如果由于任何原因阻止此线程,则事件调度线程无法处理任何新事件…

所有阻塞或长时间运行的任务都应该在Event Dispatching Thread的上下文之外执行。

有关更多详细信息,请参阅Swing中的Concurrency