Returning a Response (String or Binary)

Problem

You need to write a string or binary data to the client.

Solution

The socket gives you an InputStream and an OutputStream. Use them.

Discussion

The client socket examples in the previous chapter called the getInputStream( ) and getOutputStream( ) methods. These examples do the same. The main difference is that they get the socket from a ServerSocket’s accept( ) method, and that normally the server creates or modifies the data and writes it to the client. Example 16-3 is a simple Echo server, which the Echo client of Section 15.5 can connect to. This server handles one complete connection with a client, then goes back and does the accept( ) to wait for the next client.

Example 16-3. EchoServer.java

/**
 * EchoServer - create server socket, do I-O on it.
 */
public class EchoServer {
    /** Our server-side rendezvous socket */
    protected ServerSocket sock;
    /** The port number to use by default */
    public final static int ECHOPORT = 7;
    /** Flag to control debugging */
    protected boolean debug = true;

    /** main: construct and run */
    public static void main(String[] argv) {
        new EchoServer(ECHOPORT).handle(  );
    }

    /** Construct an EchoServer on the given port number */
    public EchoServer(int port) {
        try {
            sock = new ServerSocket(port);
        } catch (IOException e) {
            System.err.println("I/O error in setup");
            System.err.println(e);
            System.exit(1);
        }
    }

    /** This handles the connections */
    protected void handle(  ) {
        Socket ios = null;
        BufferedReader is = null;
        PrintWriter os = null;
        while (true) {
            try {
                ios = sock.accept(  );
                System.err.println("Accepted from " +
                    ios.getInetAddress().getHostName(  ));
                is = new BufferedReader(
                    new InputStreamReader(ios.getInputStream(  ), "8859_1"));
                os = new PrintWriter(
                        new OutputStreamWriter(
                            ios.getOutputStream(  ), "8859_1"), true);
                String echoLine;
                while ((echoLine = is.readLine(  )) != null) {
                    System.err.println("Read " + echoLine);
                    os.print(echoLine + "
");
                    System.err.println("Wrote " + echoLine);
                }
                System.err.println("All done!");
            } catch (IOException e) {
                System.err.println(e);
            } finally {
                try {
                    if (is != null)
                        is.close(  );
                    if (os != null)
                        os.close(  );
                    if (ios != null)
                        ios.close(  );
                } catch (IOException e) {
                    // These are unlikely, but might indicate that
                    // the other end shut down early, a disk filled up
                    // but wasn't detected until close, etc.
                    System.err.println("IO Error in close");
                }
            }
        }
        /*NOTREACHED*/
    }
}

To send a string across an arbitrary network connection, some authorities recommend sending both the carriage return and the newline character. This explains the in the code. The reason is that if the other end is a DOS program or a Telnet-like program, it may be expecting both characters. On the other hand, if you are writing both ends, you can simply use println( ) , followed always by an explicit flush( ) before you read, to prevent the deadlock of having both ends trying to read with one end’s data still in the PrintWriter’s buffer!

If you need to process binary data, use the data streams from java.io instead of the readers/writers. I need a server for the DaytimeBinary program of Section 15.6. In operation, it should look like the following.

C:javasrc
etwork>java DaytimeBinary
Reme time is 3161316799
BASE_DIFF is 2209032000
Time diff == 952284799
Time on localhost is Sun Mar 05 19:33:19 GMT 2000

C:javasrc
etwork>time
Current time is  7:33:23.84p
Enter new time:

C:javasrc
etwork>date
Current date is Sun 03-05-2000
Enter new date (mm-dd-yy):

C:javasrc
etwork>

Well, it happens that I have such a program in my arsenal, so I present it in Example 16-4. Note that it directly uses certain public constants defined in the client class. Normally these are defined in the server class and used by the client, but I wanted to present the client code first.

Example 16-4. DaytimeServer.java (binary server protocol)

/**
 * DaytimeServer - send the binary time.
 */
public class DaytimeServer {
    /** Our server-side rendezvous socket */
    ServerSocket sock;
    /** The port number to use by default */
    public final static int PORT = 37;

    /** main: construct and run */
    public static void main(String[] argv) {
        new DaytimeServer(PORT).runService(  );
    }

    /** Construct an EchoServer on the given port number */
    public DaytimeServer(int port) {
        try {
            sock = new ServerSocket(port);
        } catch (IOException e) {
            System.err.println("I/O error in setup
" + e);
            System.exit(1);
        }
    }

    /** This handles the connections */
    protected void runService(  ) {
        Socket ios = null;
        DataOutputStream os = null;
        while (true) {
            try {
                System.out.println("Waiting for connection on port " + PORT);
                ios = sock.accept(  );
                System.err.println("Accepted from " +
                    ios.getInetAddress().getHostName(  ));
                os = new DataOutputStream(ios.getOutputStream(  ));
                long time = System.currentTimeMillis(  );

                time /= DaytimeBinary.MSEC;    // Daytime Protocol is in seconds

                // Convert to Java time base.
                time += DaytimeBinary.BASE_DIFF;

                // Write it, truncating cast to int since it is using
                // the Internet Daytime protocol which uses 4 bytes.
                // This will fail in the year 2038, along with all
                // 32-bit timekeeping systems based from 1970.
                // Remember, you read about the Y2038 crisis here first!
                os.writeInt((int)time);
                os.close(  );
            } catch (IOException e) {
                System.err.println(e);
            }
        }
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.104.153