简体   繁体   中英

What is a good way to handle command read from user and server's response in a remote command-line interpreter?

I'm implementing a client side software that lets user input commands, sends them to a server, the server interprets them and sends the result to the client. Here's where I'm stuck, I have a while loop that gets responses from server until the connection ends.

try(Socket socket = new Socket(hostname, port);
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))){

    System.out.println("Connected to " + hostname + ":" + port + " !");

    Scanner scanner = new Scanner(System.in);
    String command = scanner.nextLine();
    String fromServer = null;
    int status;
    HashMap<String, String> response;
    long start = 0;

    System.out.println("C:" + command);

    if (command.toLowerCase().equals("exit")) return;

    out.println(command);

    if (command.toLowerCase().equals("shutdown")) return;

    out.println();

    while ((fromServer = in.readLine()) != null) {

        // Here's my problem
        response = parseResponse(fromServer);

        if (response.containsKey("response")) response.put("response", response.get("response").replaceAll("\\\\n", "\n"));

        try {

            status = Integer.parseInt(response.get("status"));

        } catch (NumberFormatException e){

            status = Status.RESPONSE_CORRUPTED;

        }

        System.out.println("S:" + status + (response.get("response") != null ? "\n" + response.get("response") : ""));
        command = scanner.nextLine();
        System.out.println("C:" + command);
        out.println(command);

    }

} catch (IOException e){

    System.out.println("Server isn't connected, try again later.");

}

The real problem is that I need to put

if (command.toLowerCase().equals("exit")) return;

out.println(command);

if (command.toLowerCase().equals("shutdown")) return;

out.println();

before the while, so there's three out.println() in the code while one would be more "logic" and I need to put

if (command.toLowerCase().startsWith("shutdown") && fromServer.equalsIgnoreCase("0") || status == Status.RESPONSE_CORRUPTED) break;

in that while so the client stops directly when the command shutdown is sent (to shutdown the server) to prevent the user from entering another command. I'm searching for a more efficient way to manage commands and to add a ping command (but I need to add an if before the one to shutdown), maybe using more OOP but I don't see how to do it.

I think you should give a try to Spring Shell first before attempting to make your own from scratch. It is quite modular and you can create the backend handlers that send the commands to the remote server.

Use an infinite loop and break it based on the user input or on the server response

Here is an example which does not send the exit/shutdown commands to the server, but rather they only stop the client. If you need to send all the commands to the server and stop only based on the server response then just delete the if statement from the while loop

    Scanner scanner = new Scanner(System.in);
    String command = null;
    while (true) {

        command = scanner.nextLine();

        if (command.toLowerCase().equals("exit") || command.toLowerCase().equals("shutdown")) {
            break;
        }

        out.print(command);
        out.flush();

        String response = in.readLine();

        // do something with the response (ex. stop the client by calling break or just print the response

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM