为什么我的客户端在等待服务器的响应时会冻结?

时间:2014-12-05 16:51:00

标签: java swing sockets serversocket

我有两个独立的Java项目,一个是客户端,另一个是服务器。服务器设置为从客户端获取特定命令,并根据命令响应命令。

以下是客户端的连接部分:

private class Controller implements ActionListener {
    private final long SLEEP_TIME = 100L;
    private PrintWriter pw;
    private BufferedReader br;
    private Socket socket;
    private static final String serverPrompt = "SERVER>";
    private static final String clientPrompt = "CLIENT>";

    @Override
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();
        String command = event.getActionCommand();
        if (source instanceof JButton) {
            if (command.equals("Send")) {
                if (socket != null) {
                    String fromServer = null;
                    try {
                        pw.println(commandTextField.getText());
                        try {
                            System.out.println("HERE!");
                            Thread.sleep(SLEEP_TIME);
                        } catch (InterruptedException ie) {
                            ie.printStackTrace();
                        } // end catch
                        while ((fromServer = br.readLine()) != null) {
                            System.out.printf("RECEIVED COMMAND %s\n", fromServer);
                            if (fromServer.startsWith("END"))
                                break;
                            if (fromServer.startsWith("CLS"))
                                terminalTextArea.setText("");
                            if (fromServer.startsWith("?")) {
                                String s = null;
                                br.readLine();
                                terminalTextArea.append(serverPrompt + br.readLine() + "\n");
                                while ((s = br.readLine()) != null) {
                                    terminalTextArea.append(s + "\n");
                                }
                            }
                            else {
                                terminalTextArea.append(serverPrompt + fromServer);
                                //terminalTextArea.append(bw.readLine());
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally { // start finally block
                        try {
                            fromServer = br.readLine();
                            terminalTextArea.append(serverPrompt + fromServer);
                            terminalTextArea.append(clientPrompt + fromServer);
                            pw.close(); // close the output stream
                            br.close(); // close the input stream
                        } catch (IOException ioex) { // closing the resources fails
                            ioex.printStackTrace();
                        } // end catch block
                    } // end finally block
                } else {
                    terminalTextArea.append(clientPrompt + "ERROR: Connection refused: server is not available. Check port or restart server.");
                }
            }
        }
        if (command.equals("Connect")) {
            try {
                socket = new Socket(hostTextField.getText(), portComboBox.getItemAt(portComboBox.getSelectedIndex()));
                terminalTextArea.setText("Connecting to a client Socket[addr=" + socket.getInetAddress().toString()
                         + ",port=" + socket.getPort() + ",localport=" + socket.getLocalPort() + "]\n");
                pw = new PrintWriter(socket.getOutputStream(), true);
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                sendButton.setEnabled(true);
                connectButton.setEnabled(false);
                connectButton.setBackground(Color.BLUE);
            } catch (UnknownHostException uhex) {
                uhex.printStackTrace();
            } catch (IOException ioex) {
                ioex.printStackTrace();
            }
        }
    }
}

客户端的GUI已经构建并按照我​​的意图运行。 connectionButton是私人字段JButton引用,同样sendButtonsendButton使用已建立的套接字将命令发送到服务器。然后,我希望客户端收听服务器的响应。

连接的服务器代码如下所示:

public class ServerSocketRunnable implements Runnable { // start class ServerSocketRunnable
    private final long SLEEP_TIME = 100L;
    private String command;
    private String fullCommand;
    private String[] commands = { "END", "ECHO", "TIME", "DATE", "?", "CLS" };
    private Socket socket;
    private PrintWriter pw;
    private BufferedReader br;

    public ServerSocketRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() { // start run()
        try {
            pw = new PrintWriter(socket.getOutputStream(), true);
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.printf("Connecting to a client Socket[addr=%s,port=%d,localport=%d]\n",
                    socket.getInetAddress().toString(), socket.getPort(), socket.getLocalPort());
            Calendar cal = Calendar.getInstance();
            while ((fullCommand = br.readLine()) != null) {
                int index = fullCommand.indexOf(">");
                if (index >= 0)
                    command = fullCommand.substring(0, index);
                else
                    command = fullCommand;
                System.out.printf("COMMAND: %s", command);
                switch (command) { // start switch
                case "ECHO": // repeat sent command back to Client
                    String optString = fullCommand.substring(fullCommand.indexOf(">") + 1, fullCommand.length());
                    pw.print(command);
                    pw.printf(": %s\n", optString.trim());
                    break;
                case "TIME": // time command
                    DateFormat timeFormat = new SimpleDateFormat("hh:mm:ss a");
                    pw.print(command);
                    pw.printf(": %s\n", timeFormat.format(cal.getTime()));
                    break;
                case "DATE": // date command
                    DateFormat dateFormat = new SimpleDateFormat("d MMMM yyyy");
                    pw.print(command);
                    pw.printf(": %s\n", dateFormat.format(cal.getTime()));
                    break;
                case "?": // help command
                    pw.print(command);
                    pw.println("AVAILABLE SERVICES:");
                    for (String c : commands) {
                        pw.println(c);
                    }
                    break;
                case "CLS": // clear command
                    pw.println(command);
                    break;
                case "END": // end command
                    pw.println(command);
                    break;
                default: // command received from Client was not valid
                    pw.println("ERROR: Unrecognized command.");
                    break;
                } // end switch
                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                } // end catch
            } // end while
        } catch (IOException ioex) { // communication with the Client fails
            ioex.printStackTrace();
        } // end catch block
        finally { // start finally block
            try {
                pw.println("Connection closed");
                pw.close(); // close the output stream
                br.close(); // close the input stream
            } catch (IOException ioex) { // closing the resources fails
                ioex.printStackTrace();
            } // end catch block
        } // end finally block
    } // end run()
} // end class ServerSocketRunnable 

服务器已经向客户端返回了正确的信息,但?命令除外,它只返回命令AVAILABLE SERVICES?命令还应该返回commands数组中的数据。 END命令也有点奇怪,因为它应该在服务器从客户端确认END后终止连接。

我还在等待服务器响应时遇到客户端挂起。 GUI变得完全没有响应,我必须强制关闭它以尝试另一个测试。谁能告诉我为什么我的客户变得反应迟钝?我非常感谢!

0 个答案:

没有答案