简体   繁体   中英

How do I fixed skipped input/output lines in Java Echo Server?

New to network computing, so forgive my ignorance:

All of my commands work except for the /caesarcipher - when I enter it, I don't receive an echo until the next message on the client side, and the server doesn't begin to perform the function until 2 subsequent messages have been sent.

Any help would be appreciated!

import java.net.*;
import java.io.*;
import java.util.concurrent.TimeUnit;

public class EchoServer{

    public static void main(String[] args) throws Exception {
        //Initializes and attempts to connect server
        ServerSocket serverSock = null;
        try{
            serverSock = new ServerSocket(8000);
        }
        catch (IOException ie){
            System.out.println("[SERVER DISCONNECTED!] Can't listen on 8000");
            System.exit(1);
        }
        Socket link = null;
        System.out.println("[SERVER CONNECTED!] Listening for connection ...");
        try {
            link = serverSock.accept();
        }
        catch (IOException ie){
            System.out.println("[SERVER DISCONNECTED!] Accept failed");
            System.exit(1);
        }

        //Connects client if handshake is successful
        System.out.println("[CLIENT CONNECTED!] Link Information:" + link);
        System.out.println("Listening for input ...");

        //Initializes input and output streams
        PrintWriter output = new PrintWriter(link.getOutputStream(), true);
        BufferedReader input = new BufferedReader(new InputStreamReader(link.getInputStream()));
        String inputLine;
        while ((inputLine = input.readLine())!=null) {
            String currentMessage = inputLine;
            System.out.println("[SERVER:] " + currentMessage);
            switch(currentMessage){
                case "/myip":                                           //Looks up local IP address of client
                    MyLocalIPAddress myIP = new MyLocalIPAddress();
                    String ip = myIP.run();
                    output.println(ip);
                    System.out.println(ip);
                    break;
                case "/iplookup":                                       //Looks up IP of user input website
                    IPFinder ipFinder = new IPFinder();
//  TO DO:              UrlValidator validator = new UrlValidator();
                    System.out.println("[REQUESTING URL FROM CLIENT!]");
                    output.println("Enter Website URL:");
                    inputLine = input.readLine();
                    System.out.println("Server: " + inputLine);
//  TO DO:          if(validator.isValid(inputLine)) {                    //Regex to validate user input
                    String ipAddress = ipFinder.find(inputLine) + " ==>  [IPLOOKUP TERMINATING]";
                    System.out.println(ipAddress);
                    output.println(ipAddress);
                    System.out.println("[IPLOOKUP FUNCTION TERMINATING!]");
                    break;

                case "/numbergame":                                         //Starts a number guessing game
                    boolean isPlaying;
                    int randomNumber = -1;
                    final int maxNum = 100;
                    System.out.println("[CLIENT HAS INITIATED GUESS THE NUMBER GAME!]");
                    output.println("Would you like to play the number game (Y/N)?");
                    inputLine = input.readLine();
                    if(inputLine.equalsIgnoreCase("Y")){
                        System.out.println("[CLIENT REQUESTS TO BEGIN A GAME!]");
                        isPlaying = true;
                        System.out.println("[SERVER IS PICKING A RANDOM NUMBER!]");
                        output.println("Enter A Number Between 0-100 (/endgame to quit)");
                        randomNumber = (int) Math.floor(Math.random() * maxNum + 1);
                        System.out.println("[RANDOM NUMBER IS: " + randomNumber + "]");
                    }else if(inputLine.equalsIgnoreCase("N")){
                        System.out.println("[GUESS THE NUMBER GAME ABORTING]");
                        output.println("Quitting guess the number game");
                        isPlaying = false;
                    }else{
                        System.out.println("[CLIENT PROVIDED FAULTY INPUT, GAME ABORTING!]");
                        output.println("Input not recognized, game aborting!");
                        isPlaying = false;
                    }

                    while(isPlaying) {
                        System.out.println("[REQUESTING NUMBER FROM CLIENT!]");
                        inputLine = input.readLine();
                        if (inputLine.equalsIgnoreCase("/endgame")) {
                            isPlaying = false;
                        }
                        if (isNumeric(inputLine)) {
                            int currentGuess = Integer.parseInt(inputLine);
                            if (randomNumber == currentGuess) {
                                System.out.println("[CLIENT HAS GUESSED THE CORRECT NUMBER, GAME TERMINATING!]");
                                output.println("You have guessed correctly! Game ending!");
                                isPlaying = false;
                            } else if (currentGuess > randomNumber) {
                                System.out.println("[CLIENT GUESSED TOO HIGH!]");
                                output.println("Too high! Guess again!");
                            } else if (currentGuess < randomNumber) {
                                System.out.println("[CLIENT GUESSED TOO LOW!]");
                                output.println("Too low! Guess again!");
                            }
                        }else if(inputLine.equalsIgnoreCase("/endgame")){
                            System.out.println("[CLIENT HAS REQUESTED TO END GAME - TERMINATING...]");
                            output.println("Quitting game, better luck next time!");
                            break;

                        }else{
                            System.out.println("[CLIENT HAS PROVIDED INCORRECT INPUT]");
                            output.println("You have not entered a valid number, try again!");
                        }
                    }
                    break;

                case "/caesarcipher":
                    int maxKeyValue = 25;

                    int randomKey = (int) Math.floor(Math.random() * maxKeyValue + 1);
                    System.out.println("[CLIENT HAS INITIATED CAESAR CIPHER PROGRAM ----- CLIENT CAESAR CIPHER IS "
                            + randomKey + " (Type 'bye' to exit)!]");
                    output.println("Your Caesar Cipher is " + randomKey + ". Enter a message to encrypt: ");

                    while((inputLine = input.readLine()) != null) {
                        if (inputLine.equalsIgnoreCase("/caesarcipher")) {
                            output.println("Your Caesar Cipher is " + randomKey + ". Enter a message to encrypt: ");
                            output.flush();
                        }else if (inputLine.equalsIgnoreCase("/bye") ||
                                inputLine.equalsIgnoreCase("bye")) {
                            System.out.println("[CLIENT HAS REQUESTED TO END CAESAR CIPHER MODE!]");
                            output.println("Quitting Caesar cipher mode...");
                            break;
                        }else{
                            CaesarCipher caesarCipher = new CaesarCipher();
                            currentMessage = input.readLine();
                            String decryptedMessage = caesarCipher.decrypt(currentMessage, randomKey);
                            System.out.println("[SERVER:] Received: " + currentMessage + " ==> " +
                                    decryptedMessage);
                        }
                    }

                    break;

                case "/secretmessage":
                    System.out.println("♡♡♡♡♡♡ Shahnaz ♡♡♡♡♡♡");
                    output.println("♡♡♡♡♡♡ Shahnaz ♡♡♡♡♡♡");
                    break;

                case "/killserver":
                    System.out.println("[CLIENT REQUESTED SERVER SHUTDOWN!]");
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("[SERVER IS SHUTTING DOWN!");
                    TimeUnit.SECONDS.sleep(1);
                    closeServer(output, input, link, serverSock);
                    System.exit(1);
                    break;

                case "exit":
                case "quit":
                case "disconnect":
                    disconnectClient(output, input, link, serverSock);
                    break;
                default:
                    output.println(currentMessage);
            }
        }
    }
    public static void closeServer(PrintWriter output, BufferedReader input, Socket link, ServerSocket serverSock)
            throws IOException {
        System.out.println("[CLIENT REQUESTED TO CLOSE SERVER!");
        output.close();
        input.close();
        link.close();
        serverSock.close();
    }

    public static void disconnectClient(PrintWriter output, BufferedReader input, Socket link, ServerSocket serverSock)
            throws IOException, InterruptedException {
        output.println("[CLIENT REQUESTED TO CLOSE CONNECTION!");
        TimeUnit.SECONDS.sleep(5);
        output.println("[DISCONNECTING!");
        output.close();
        input.close();
        link.close();
    }

    //Tests to see if a string contains all numeric values
    public static boolean isNumeric(String str) {
        for (char c : str.toCharArray()){
            if (!Character.isDigit(c)) return false;
        }
        return true;
    }
}
import java.io.*;
import java.net.*;

public class EchoClient{
    public static void main(String[] args) throws IOException{
        Socket link = null;
        PrintWriter output = null;
        BufferedReader input = null;
        Boolean cipherModeActive = true;

        try{
            System.out.println("[CONNECTING TO SERVER ON PORT 8000]");
            link = new Socket(InetAddress.getLocalHost(), 8000);
            output = new PrintWriter(link.getOutputStream(), true);
            input = new BufferedReader(new InputStreamReader(link.getInputStream()));
            System.out.println("[CONNECTED TO SERVER]");
        }
        catch(UnknownHostException e)
        {
            System.out.println("Unknown Host");
            System.exit(1);
        }
        catch (IOException e){
            System.out.println("Cannot connect to host");
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader((new InputStreamReader(System.in)));
        String usrInput;

        System.out.println("Welcome to the Server!\n\n" +
                "----- Here is a List Options: ----- \n " +
                "/myip ----- will allow you to look up your ip address\n" +
                "/iplookup ----- will allow you to look up the ip of a URL\n" +
                "/numbergame ----- allows you to play a guess the number game\n" +
                "/caesarcipher ----- allows you to encrypt and decrypt server messages using a caesar cipher\n" +
                "/exit, /quit, /disconnect ---- allows you to disconnect from the server\n\n" +
                "Enter a message:");

        //User Input
        boolean cipherActive = false;
        while ((usrInput = stdIn.readLine())!=null){
            output.println(usrInput);
            String message = input.readLine();

            if(usrInput.equalsIgnoreCase("/caesarcipher")){
                cipherActive = true;
            }

            if(!cipherActive){
                System.out.println("echo: " + message);
                output.flush();
            }
            if(cipherActive) {
                CaesarCipher caesarCipher = new CaesarCipher();
                String serverKeyMessage = message;
                int serverKey = Integer.parseInt(serverKeyMessage.replaceAll("[^0-9]", ""));
                while ((usrInput = stdIn.readLine()) != null) {
                    message = usrInput;
                    if (usrInput.equalsIgnoreCase("/caesarcipher")){
                        output.flush();
                    }else if (usrInput.equalsIgnoreCase("/bye")
                            || usrInput.equalsIgnoreCase("bye")) {
                        break;
                    }
                    //Encrypts message to send to server

                    //Prints server response to client
                    if (!message.equalsIgnoreCase("/caesarcipher")) {
                        String currentMessage = usrInput;
                        String encryptedMessage = caesarCipher.encrypt(currentMessage, serverKey);
                        output.println(encryptedMessage);
                        System.out.println("echo: " + message);
                    }
                }
                break;
            }
        }

        switch(usrInput) {
//          case "echo: Enter Website URL:":
//          case "iplookup terminating...":
//          case "Would you like to play the number game (Y/N)?":
//          case "You have guessed correctly! Game ending!":
//          case "echo: Enter a message to encrypt: ":
//              output.flush();

            case "echo: /quit":
            case "echo: /disconnect":
            case "echo: /killserver":
                output.close();
                input.close();
                stdIn.close();
                link.close();
                break;
        }
        //Flushes output for number game
        if(isNumeric(usrInput)){
            output.flush();
        }
    }
    //Checks string for numerical values and returns true if all numeric, false if other characters are present

    public static boolean isNumeric(String str) {
        for (char c : str.toCharArray()){
            if(!Character.isDigit(c)) return false;
        }
        return true;
    }
}
import com.sun.org.apache.bcel.internal.generic.ARETURN;

import java.util.*;

public class CaesarCipher {
    public static String encrypt(String stringToEncrypt, int offset) {
        String ciphertext = "";
        char alphabet;
        for(int i=0; i < stringToEncrypt.length();i++)
        {
            // Shift one character at a time
            alphabet = stringToEncrypt.charAt(i);

            // if alphabet lies between a and z
            if(alphabet >= 'a' && alphabet <= 'z')
            {
                // shift alphabet
                alphabet = (char) (alphabet + offset);
                // if shift alphabet greater than 'z'
                if(alphabet > 'z') {
                    // reshift to starting position
                    alphabet = (char) (alphabet+'a'-'z'-1);
                }
                ciphertext = ciphertext + alphabet;
            }

            // if alphabet lies between 'A'and 'Z'
            else if(alphabet >= 'A' && alphabet <= 'Z') {
                // shift alphabet
                alphabet = (char) (alphabet + offset);

                // if shift alphabet greater than 'Z'
                if(alphabet > 'Z') {
                    //reshift to starting position
                    alphabet = (char) (alphabet+'A'-'Z'-1);
                }
                ciphertext = ciphertext + alphabet;
            }
            else {
                ciphertext = ciphertext + alphabet;
            }
        }
        return(ciphertext);

    }
    public static String decrypt(String stringToEncrypt, int offset) {
        int decryptKey = 26-offset;
        String ciphertext = "";
        char alphabet;
        for(int i=0; i < stringToEncrypt.length();i++)
        {
            // Shift one character at a time
            alphabet = stringToEncrypt.charAt(i);

            // if alphabet lies between a and z
            if(alphabet >= 'a' && alphabet <= 'z')
            {
                // shift alphabet
                alphabet = (char) (alphabet + decryptKey);
                // if shift alphabet greater than 'z'
                if(alphabet > 'z') {
                    // reshift to starting position
                    alphabet = (char) (alphabet+'a'-'z'-1);
                }
                ciphertext = ciphertext + alphabet;
            }

            // if alphabet lies between 'A'and 'Z'
            else if(alphabet >= 'A' && alphabet <= 'Z') {
                // shift alphabet
                alphabet = (char) (alphabet + decryptKey);

                // if shift alphabet greater than 'Z'
                if(alphabet > 'Z') {
                    //reshift to starting position
                    alphabet = (char) (alphabet+'A'-'Z'-1);
                }
                ciphertext = ciphertext + alphabet;
            }
            else {
                ciphertext = ciphertext + alphabet;
            }
        }
        return(ciphertext);

    }

}
import java.net.*;
import java.util.Scanner;
public class IPFinder {
    public static String find(String host) throws Exception {
        try {
            InetAddress address = InetAddress.getByName(host);
            return ("IP address: " + address);
        } catch (UnknownHostException e) {
            return ("  Could not find " + host);
        }
    }
}

To be frankly, there are too much to read through, it would be better if you described some part of your codes more specifically, and there would be more people be willing to help you. Nonetheless, here are some suggestions for your codes, hope this helps.


For your 1st question "...I don't receive an echo until the next message on the client side..." :

Changes in EchoClient :

    // ...

    CaesarCipher caesarCipher = new CaesarCipher();
    String serverKeyMessage = message;

    /* --- Delete 1 line : */
    // int serverKey = Integer.parseInt(serverKeyMessage.replaceAll("[^0-9]", ""));

    /* +++ Add 5 lines : */
    int serverKey;
    java.util.regex.Matcher m = Pattern.compile(".*([0-9]+).*").matcher(serverKeyMessage);
    if (m.matches()) serverKey = Integer.parseInt(m.group(1));
    else serverKey = 0;
    System.out.println(serverKeyMessage);

    // ...

For your 2nd question "...doesn't begin to perform the function until 2 subsequent..." :

Changes in EchoServer :

    // ...

    CaesarCipher caesarCipher = new CaesarCipher();
    //  currentMessage = input.readLine();   // delete this line
    currentMessage = inputLine;   // add this line
    String decryptedMessage = caesarCipher.decrypt(currentMessage, randomKey);
    
    // ...

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