views:

186

answers:

2

I'm trying to write a client and time server for an assignment and I'm having trouble getting the server to receive the second request from the client. The first request goes through fine without a hitch. then it just stalls. I'm actually pretty lost in this whole thing and rather uncomfortable with java still, so I have no idea what I'm missing. Any pointers are greatly appreciated. Thanks!

Here's the sever code:

 import java.io.*;
 import java.util.*;
 import java.net.*;
 import java.text.*;

 public class myServer {

      protected static final int PORT_NUMBER = 55555;

      public static void main( String args[]) {

      try {

           ServerSocket servsock = new ServerSocket(PORT_NUMBER);

           System.out.println("Server running...");

           while(true) {

                Socket sock = servsock.accept();

                System.out.println("Connection from: " + sock.getInetAddress());

                Scanner in = new Scanner(sock.getInputStream());
                PrintWriter out = new PrintWriter(sock.getOutputStream());
                String request = "";

                request = in.next();

                System.out.println("Request: " + request);

                if(request.toUpperCase().equals("TIME")) {
                     out.println(getTime());
                     out.flush();
                } else {
                     out.println("Invalid Request...");
                     out.flush();
                }

            }

        } catch(Exception e) {
           System.out.println(e.toString());
        }

    }

      protected static String getTime() {
           DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
           Date date = new Date();
           return (dateFormat.format(date));
      }

}

Here's the Client:

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

 public class myClient {

        protected static final String HOST = "127.0.0.1";
        protected static final int PORT = 55555;

        protected static Socket sock;

        public static void main(String args[]) {

        try {

              sock = new Socket(HOST,PORT);

              System.out.println("Connected to " + HOST + " on port " + PORT);

              Scanner response = new Scanner(sock.getInputStream());
              PrintWriter request = new PrintWriter(sock.getOutputStream());
              BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
              String txt = "";

              while(!txt.toUpperCase().equals("EXIT")) {

                    System.out.print("prompt:");
                    txt = in.readLine();

                    request.println(txt);
                    request.flush();

                    System.out.println(response.next());

              }

              request.close();
              response.close();
              in.close();
              sock.close();

           } catch(IOException e) {
              System.out.println(e.toString());
           }
      }

 }
+2  A: 

From the PrintWriter docs:

...if automatic flushing is enabled it will be done only when one of the println, printf, or format methods is invoked...

Your server is calling print() and never flushes the stream, so the time never gets sent. Either call println() or explicitly flush the stream.

Also, the server closes the connection immediately after sending the time, so the client's second request always fails...

Edit: there's an interesting quirk here - closing the PrintWriter ought to flush it (see the spec of Writer), but due to the order of operations what seems to happen instead is:

  1. in.close() closes the underlying Socket
  2. out.close() would flush the data written, but can't (as the socket is now closed)

Not sure this is exactly what's happening, but swapping the order of these two statements changes the behaviour, presumably giving out.close() a chance to flush...

SimonJ
thanks, I've changed a few things and I finally got the two to communicate. However, it is still not accepting a second request. I'm updating the code in the question to the current version. Any ideas?
seventeen
After reading the first request, the server just throws away the connection and calls `servsock.accept()` again, causing it to wait for a *new* client to connect.
SimonJ
+2  A: 

You need to have another while loop, something like this,

  while(true) {                
      Socket sock = servsock.accept();                
      System.out.println("Connection from: " + sock.getInetAddress());                
      Scanner in = new Scanner(sock.getInputStream());                
      PrintWriter out = new PrintWriter(sock.getOutputStream());                
      String request = "";                
      while (in.hasNext()) {
          request = in.next();                
          System.out.println("Request: " + request);                
          if(request.toUpperCase().equals("TIME")) {                     
              out.println(getTime());
              out.flush();                
          } else {
               out.println("Invalid Request...");                     
               out.flush();
          }
      }
 }
ZZ Coder
Thank you so much! I've been flipping out over this for so long now. I don't know why I didn't see it, but THANK YOU!
seventeen