我有两个独立的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
引用,同样sendButton
。 sendButton
使用已建立的套接字将命令发送到服务器。然后,我希望客户端收听服务器的响应。
连接的服务器代码如下所示:
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变得完全没有响应,我必须强制关闭它以尝试另一个测试。谁能告诉我为什么我的客户变得反应迟钝?我非常感谢!