0

I have two separate Java projects, one a client and one a server. The server is set up to take specific commands from a client and respond to the command depending on what it is.

The following is the connection portion of the client:

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();
            }
        }
    }
}

The GUI for the client is built already and works as I intend it to. connectionButton is a private field JButton reference and sendButton is likewise. The sendButton sends the command to the server using the established socket. I would then like the client to listen to a response from the server.

The server code for the connection looks like this:

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 

The server already returns the proper information to the client, except the ? command which only returns the command and AVAILABLE SERVICES. The ? command should also return the data in the commands array. The END command is also kind of weird, as it is supposed to terminate the connection after the server acknowledges the END from the client.

I also experience the client hanging when it is waiting for a server response. The GUI becomes completely unresponsive and I have to force close it to try another test. Can anybody tell me why my client is becoming unresponsive? I would very much appreciate it!

Benjamin
  • 345
  • 2
  • 3
  • 15
  • 2
    Don't make hanging calls on the EDT. Use a `SwingWorker`. – jtahlborn Dec 05 '14 at 16:53
  • @jtahlborn What types would a SwingWorker class in this context use? I'd assume I'd be returning the `String` commands? And processing `String` data as well? So I'd declare a class extending `SwingWorker`, since `SwingWorker` is abstract? – Benjamin Dec 05 '14 at 17:00
  • Check the [tutorial](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) or just search this site for [similar questions](http://stackoverflow.com/search?tab=votes&q=%5bswing%5d%20socket%20freezes%20body%3aswingworker) (please check the links). – Hovercraft Full Of Eels Dec 05 '14 at 17:03
  • [Link to another similar question/answer](http://stackoverflow.com/a/19552923/522444). – Hovercraft Full Of Eels Dec 05 '14 at 17:08

0 Answers0