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!