Java SimpleClient & SimpleServer Sending Commands Being Weird

83 Views Asked by At

Hi Stackover flow world,

Thought I'd send something over as I haven't shared a question in some time. I've been pretty stumped on the weirdest, possibly simplest question ever, that I've been finding all sorts of different responses online.

Basically, I have a SimpleServer which looks as so:

// A generic server that listens on a port and connects to any clients it
// finds. Made to extend Thread, so that an application can have multiple
// server threads servicing several ports, if necessary.

public class SimpleServer
{
    protected int portNo = 8082; // Port to listen to for clients
    protected ServerSocket clientConnect;

    public SimpleServer(int port) throws IllegalArgumentException {
        if (port <= 0)
            throw new IllegalArgumentException(
                    "Bad port number given to SimpleServer constructor.");

        // Try making a ServerSocket to the given port
        System.out.println("Connecting server socket to port...");
        try { clientConnect = new ServerSocket(port); }
        catch (IOException e) {
            System.out.println("Failed to connect to port " + port);
            System.exit(1);
        }

        // Made the connection, so set the local port number
        this.portNo = port;
    }

    public static void main(String argv[]) {
        int port = 8088;
        if (argv.length > 0) {
            int tmp = port;
            try {
                tmp = Integer.parseInt(argv[0]);
            }
            catch (NumberFormatException e) {}

            port = tmp;
        }

        SimpleServer server = new SimpleServer(port);
        System.out.println("SimpleServer running on port " + port + "...");
        server.listen();
    }

    public void listen() {
        // Listen to port for client connection requests.
        try {
            System.out.println("Waiting for clients...");
            while (true) {
                Socket clientReq = clientConnect.accept();
                System.out.println("Got a client...");
                serviceClient(clientReq);
            }
        }
        catch (IOException e) {
            System.out.println("IO exception while listening for clients.");
            System.exit(1);
        }
    }

    public void serviceClient(Socket clientConn) {
        SimpleCmdInputStream inStream = null;
        DataOutputStream outStream = null;
        try {
            inStream = new SimpleCmdInputStream(clientConn.getInputStream());
            outStream = new DataOutputStream(clientConn.getOutputStream());
        }
        catch (IOException e) {
            System.out.println("SimpleServer: Error getting I/O streams.");
        }

        SimpleCmd cmd = null;
        System.out.println("Attempting to read commands...");
        while (cmd == null || !(cmd instanceof DoneCmd)) {
            try { cmd = inStream.readCommand(); }
            catch (IOException e) {
                System.out.println("SimpleServer: " + e);
                System.exit(1);
            }

            if (cmd != null) {
                String result = cmd.Do();
                try { outStream.writeBytes(result); }
                catch (IOException e) {
                    System.out.println("SimpleServer: " + e);
                    System.exit(1);
                }
            }
        }
    }

    public synchronized void end() {
        System.out.println("Shutting down SimpleServer running on port "
                + portNo);
    }
}

Then I have a SimpleClient which looks as so:

public class SimpleClient
{
    // Our socket connection to the server
    protected Socket serverConn;

    // The input command stream from the server
    protected SimpleCmdInputStream inStream;

    public SimpleClient(String host, int port)
            throws IllegalArgumentException {
        try {
            System.out.println("Trying to connect to " + host + " " + port);
            serverConn = new Socket(host, port);
        }
        catch (UnknownHostException e) {
            throw new IllegalArgumentException("Bad host name given.");
        }
        catch (IOException e) {
            System.out.println("SimpleClient: " + e);
            System.exit(1);
        }

        System.out.println("Made server connection.");
    }

    public static void main(String argv[]) {
        if (argv.length < 2) {
            System.out.println("Usage: java SimpleClient [host] [port]");
            System.exit(1);
        }

        System.out.println("Getting here");

        String host = argv[0];
        int port=0;
        try {
            port = Integer.parseInt(argv[1]);
        }
        catch (NumberFormatException e) {}

        SimpleClient client = new SimpleClient(host, port);
        System.out.println("Commands are about to send?");

        client.sendCommands();
    }

    public void sendCommands() {
        try {
            OutputStreamWriter wout =
                    new OutputStreamWriter(serverConn.getOutputStream());
            BufferedReader rin = new BufferedReader(
                    new InputStreamReader(serverConn.getInputStream()));

            wout.write("what is a man is a good man\n");
            wout.flush();
            rin.readLine();

            System.out.println("getting here yo");
            // Send a GET command...
            wout.write("GET goodies ");
            // ...and receive the results
            String result = rin.readLine();
            System.out.println(result + "I am here");
            System.out.println("Server says: \"" + result + "\"");

            // Now try a POST command
            wout.write("POST goodies ");
            // ...and receive the results
            result = rin.readLine();
            System.out.println("Server says: \"" + result + "\"");

            // All done, tell the server so
            wout.write("DONE ");
            result = rin.readLine();
            System.out.println("Server says: \"" + result + "\"");
        }
        catch (IOException e) {
            System.out.println("SimpleClient: " + e);
            System.exit(1);
        }
    }

    public synchronized void end() {
        System.out.println("Closing down SimpleClient...");
        try { serverConn.close(); }
        catch (IOException e) {
            System.out.println("SimpleClient: " + e);
            System.exit(1);
        }
    }
}

Connected to the target VM, address: '127.0.0.1:64335', transport: 'socket' Getting here Trying to connect to localhost 8088 Made server connection. Commands are about to send?

Output Connected to the target VM, address: '127.0.0.1:64335', transport: 'socket' Getting here Trying to connect to localhost 8088 Made server connection. Commands are about to send?

For some reason the client freezes at 'commands are about to send', and for some reason doesn't truly 'write' to the socket when sending these commands to the server.

Any clues, am i missing something, completely off the mark here?

Thanks! Arsalan

1

There are 1 best solutions below

0
On

Figured it out, seems like there's so much drama when it comes to all the types of streams, writers, readers, etc. It seems that somehow my samples have used the types of these streams incorrectly, as the clear difference to understand is that streams are for everything that implement Output or Input Stream, and are for essentially for reading or writing binary data.

Readers & writers are a layer above streams for reading and writing text. Readers and writers convert binary data from and to characters using a character encoding.

Basically now do this in my SimpleClient

public class SimpleClient
{
    // Our socket connection to the server
    protected Socket serverConn;

    // The input command stream from the server
    protected SimpleCmdInputStream inStream;

    public SimpleClient(String host, int port)
            throws IllegalArgumentException {
        try {
            System.out.println("Trying to connect to " + host + " " + port);
            serverConn = new Socket(host, port);
        }
        catch (UnknownHostException e) {
            throw new IllegalArgumentException("Bad host name given.");
        }
        catch (IOException e) {
            System.out.println("SimpleClient: " + e);
            System.exit(1);
        }

        System.out.println("Made server connection.");
    }

    public static void main(String argv[]) {
        if (argv.length < 2) {
            System.out.println("Usage: java SimpleClient [host] [port]");
            System.exit(1);
        }

        System.out.println("Getting here");

        String host = argv[0];
        int port=0;
        try {
            port = Integer.parseInt(argv[1]);
        }
        catch (NumberFormatException e) {}

        SimpleClient client = new SimpleClient(host, port);
        client.sendCommands();
    }

    public void sendCommands() {
        try {
            DataOutputStream wout =
                    new DataOutputStream(serverConn.getOutputStream());
            DataInputStream rin = new DataInputStream(serverConn.getInputStream());

            // Send a GET command...
            wout.writeChars("GET goodies ");
            // ...and receive the results
            String result = rin.readLine();
            System.out.println("Server says: \"" + result + "\"");

            // Now try a POST command
            wout.writeChars("POST goodies ");
            // ...and receive the results
            result = rin.readLine();
            System.out.println("Server says: \"" + result + "\"");

            // All done, tell the server so
            wout.writeChars("DONE ");
            result = rin.readLine();
            System.out.println("Server says: \"" + result + "\"");
        }
        catch (IOException e) {
            System.out.println("SimpleClient: " + e);
            System.exit(1);
        }
    }

    public synchronized void end() {
        System.out.println("Closing down SimpleClient...");
        try { serverConn.close(); }
        catch (IOException e) {
            System.out.println("SimpleClient: " + e);
            System.exit(1);
        }
    }
}

Notice the new type of the output and input streams, rather than writers.

Thanks Arsalan!