package client; import java.rmi.*; import server.ServerInterface; import javax.swing.*; import java.awt.*; /**** * * Class Client is a simple illustration of a client that communicates with a * remote server using RMI. The client provides server-setup and computation * methods, detailed descriptions of which are given in the method * documentation. *

* The main method of the client accepts two command-line arguments. * The first argument is the name of the host on which the server is running. * The host name may be suffixed with a colon-delimited port number. If the * port number is not present, the rmiregistry on the remote host is assumed to * be running on the well-known port 1099. So, e.g., a legal hostname could be * "waldorf.csc.calpoly.edu" or "waldorf.csc.calpoly.edu:1098", the latter * selecting alternate registry port 1098. *

* The second command-line argument is an optional flag indicating if the * client's GUI should be displayed when it runs. If the argument is missing, * the default behavior is to display the GUI. If the second argument is * "-nd", then no GUI display is shown. Using the "-nd" argument is * useful when the client is run in a context where there is no support for a * Java GUI display, for example, running the client on a UNIX machine like * waldorf when logged into waldorf via telnet from a Windows PC. *

* See the Server class for a description * of the server that this client uses. * */ public class Client { /** * Establish communication with the server running on the given * hostname. As explained in the class documentation, the * hostname may be suffixed with colon-delimited port number. The hostname * is used to create a server name of the form * "//hostname/Server". See the documentation for the * server.Server.setupServer method for a explanation of this * server-name syntax. */ protected static void establishCommunication(String hostname) { /* * Set up the security manager if necessary. */ if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } /* * Establish communication with the server. */ try { server = (ServerInterface) Naming.lookup( "//" + hostname + "/Server"); } /* * Handle any remote exception that may occur during server set up or * execution. */ catch (Exception e) { System.err.println("Server exception: " + e.getMessage()); e.printStackTrace(); } } /** * Set up the display as a JFrame with a labeled text field. The * hostname input is the command-line argument from main. */ protected static void setupDisplay(String hostname) { /* * Allocate the frame and its innards. */ JFrame frame = new JFrame(); JPanel panel = new JPanel(); Box box = Box.createHorizontalBox(); /* * Add the text field. */ textField = new JTextField(8); box.add(new JLabel("Result of server computation: ")); box.add(textField); /* * Add border for some spacing. */ panel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); panel.add(box, BorderLayout.CENTER); /* * Add to, pack, and make visible the frame. */ frame.setTitle("Client of " + hostname); frame.getContentPane().add(panel); frame.pack(); frame.setVisible(true); } /** * Call the following methods on the remote server: *

  1. * * receiveClientInput *
  2. * * compute *
  3. * * getServerOutput *
* * Display the resulting server output in the display window, or write the * output to stdout if the display is not on. The actual computation is * very simple -- a client data value of 10 is sent to the server, to which * the server simply adds 1, resulting in an output of 11. */ protected static void performComputation() { /* * Call server methods to send data, perform computation, and get back * results. */ try { server.receiveClientInput(new ClientData(10)); server.compute(); if (displayOn) { textField.setText(server.getServerOutput().toString()); } else { System.out.println("Result of server computation: " + server.getServerOutput()); } } /* * Handle any remote exception that may occur during server execution. */ catch (Exception e) { System.err.println("Server exception: " + e.getMessage()); e.printStackTrace(); } } /** * Get the hostname from command-line argument, exiting if there is none. * Then call the methods to establish communication with server and perform * the simple computation. */ public static void main(String args[]) { /* * Make sure there's a hostname given on the command line. */ if (args.length == 0) { System.out.println( "First command-line argument must be a host name."); System.exit(0); } /* * Set up the display if the second command-line arg is != "-nd". */ if ((args.length > 1) && (args[1].equals("-nd"))) { displayOn = false; } else { displayOn = true; setupDisplay(args[0]); } /* * Establish communication and compute. */ establishCommunication(args[0]); performComputation(); } /** The remote server class; note the use of the interface type in the declaration, which means that the server implementation need not be (and typically is not) on the client machine. */ protected static ServerInterface server; /** The text field that displays the result computed by the server; the result is printed to stdout instead of this text field if the GUI display is not active */ protected static JTextField textField; /** True if the display is on, i.e., the 2nd command-line arg != "-nd" */ protected static boolean displayOn; }