//------------------------------------------------------------------- // CSE 461 - Winter 1998 // // EchoServer.java: implementation of an echo server and // a simple client // // USAGE: java EchoServer [host] // If [host] is specified, then connect to that host as a client, // otherwise run as a server. // // Andy Collins - acollins@cs.washington.edu //------------------------------------------------------------------- import java.util.*; import java.io.*; import java.net.*; class EchoServer { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // The well-known port for the server. Client and server need // to be compiled together so they get the same constant. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static int PORT = 4321; // arbitrary, >1024 public static void main (String[] args) { if (args.length == 0) RunServer (); else RunClient (args[0]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RunServer: a typical server loop. Creates a socket on the // well-known address and accepts each connection. // processes that connection until it runs out of // data, then closes and accepts another connection. // This implementation does not attempt to use // multithreading to handle multiple connections // simulataneously. // // EXERCISES: // 1) What happens if multiple clients connect at the // same time (you can determine this by reading or // by experimentation) // // 2) (Optional) Extend this code so that multiple // clients can be handled in parallel. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static void RunServer () { System.out.println ("Echo Server: starting"); try { // NOTE: no inet address, always local host ServerSocket serve = new ServerSocket (PORT); for (;;) { Socket sock = serve.accept (); System.out.println ("Opened connection..."); PrintStream output = new PrintStream (sock.getOutputStream ()); DataInputStream input = new DataInputStream (sock.getInputStream ()); // Read and reply until failure String msg = input.readLine (); while (msg != null) { output.println (msg); System.out.println (" echoed '" + msg + "'"); msg = input.readLine (); } sock.close (); System.out.println (" closed connection"); } } catch (IOException e) { System.out.println ("Server IO error, exiting"); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RunClient: a typical one-shot client. Opens a socket to the // server, then prints 10 messages and checks the // result. The client closes the connection in this // setup. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static void RunClient (String hostname) { System.out.println ("Echo Client: starting"); try { // HINT: try InetAddress.getLocalHost () for testing InetAddress hostAddr = InetAddress.getByName (hostname); Socket sock = new Socket (hostAddr, PORT); PrintStream output = new PrintStream (sock.getOutputStream ()); DataInputStream input = new DataInputStream (sock.getInputStream ()); System.out.println ("connected"); Random rand = new Random (); for (int i=0; i<10; ++i) { String msg = "Test message " + rand.nextLong (); System.out.print (" sending message '" + msg + "'... "); output.println (msg); String back = input.readLine (); if (!back.equals (msg)) System.out.println (" != '" + back + "'"); else System.out.println (" ok"); } sock.close (); System.out.println (" closing connection"); } catch (UnknownHostException e) { System.out.println ("Hostname '" + hostname + "' unknown."); } catch (IOException e) { System.out.println ("IO error connecting, sending or receiving"); } } }