/* * * $id: Client.java,v 1.4 1998/07/08 16:11:11 tparnell Exp $ * * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group. * For more information, see the * CS101 homepage or email . * * Copyright (C) 1996 Massachusetts Institute of Technology. * Please do not redistribute without obtaining permission. */ package cs101.net; import cs101.awt.ClientDialog; import java.io.*; import java.net.*; import cs101.util.StringHandler; /** * A reasonably vanilla network client. Works with Server.java. * To customize, provide it with a StringHandler, either at creation time or * later.

* * If server's hostName and port are not provided at creation time, the user * is prompted for this information using ClientDialog.

* * Copyright 1996 Massachusetts Institute of Technology * * @see cs101.net.Server * @see cs101.util.StringHandler * @see #setStringHandler * * @author Todd C. Parnell, tparnell@ai.mit.edu * @author Maciej Stachowiak, maciej@ai.mit.edu * @author Lynn Andrea Stein, las@ai.mit.edu * @version $Id: Client.java,v 1.1.1.1 2002/06/05 21:56:32 root Exp $ * */ public class Client implements Runnable, StringHandler { /** Animates this object */ protected Thread spirit; /** Handles input from net */ protected StringHandler stringHandler; /** Net connection */ protected Socket sock; /** Where to read data */ protected ObjectInputStream ois; /** Where to write data */ protected ObjectOutputStream oos; /** Flag to indicate whether the Thread animating this should stop */ private boolean stopped; /** * Creates an autonomous client. Send Strings using send; receive Strings * as this client's StringHandler (it calls your handleString method). * * @param sh the StringHandler to handle data this client receives from the net. * @param hostName the name of the machine that the server is on * @param port the port number on which the server is listening * * @see #send * @see cs101.util.StringHandler */ public Client ( String hostName, int port, StringHandler sh ) { this.stringHandler = sh; this.connectTo( hostName, port ); } /** * Creates an autonomous client. Send Strings using send; receive Strings * as this client's StringHandler (it calls your handleString method). *

* StringHandler may be set later. Otherwise, this object's default method * is used. * * @param hostName the name of the machine that the server is on * @param port the port number on which the server is listening * * @see #send * @see #setStringHandler */ public Client ( String hostName, int port ) { this.stringHandler = this; this.connectTo( hostName, port ); } /** * Creates an autonomous client. Send Strings using send; receive Strings * as this client's StringHandler (it calls your handleString method). *

* User is prompted for server's hostName and port (using ClientDialog). * * @param sh the StringHandler to handle data this client receives from the net. * * @see cs101.util.StringHandler */ public Client ( StringHandler sh ) { this.stringHandler = sh; ClientDialog qd = new ClientDialog(); qd.ask(); this.connectTo( qd.getHostName(), qd.getPort() ); } /** * Creates an autonomous client. Send Strings using send; receive Strings * as this client's StringHandler (it calls your handleString method). *

* StringHandler may be set later. Otherwise, this object's default method * is used. *

* User is prompted for server's hostName and port (using ClientDialog). * * @see #send * @see #setStringHandler */ public Client() { this.stringHandler = this; ClientDialog qd = new ClientDialog(); qd.ask(); this.connectTo( qd.getHostName(), qd.getPort() ); } /** * Opens a connection to a server presumed to be listening on hostName, * port. Sets up listener thread. Called by constructor; should not be * called otherwise. * * @param hostName the name of the machine that the server is on * @param port the port number on which the server is listening */ protected void connectTo( String hostName, int port ) { System.out.println("Client: trying to connect to " + hostName + " on port " + port ); try { this.sock = new Socket( hostName, port ); // create Output before Input this.oos = new ObjectOutputStream(this.sock.getOutputStream()); this.ois = new ObjectInputStream(this.sock.getInputStream()); } catch (IOException e) { throw new RuntimeException("Client: " + "can't establish communication with " + hostName + " on port " + port ); } this.spirit = new Thread( this ); this.spirit.start(); } /** * Reads Strings from the server connection. Called by this object's Thread. * Should not be called otherwise. */ public void run() { System.out.println( "Client: starting read loop." ); try { while ( !this.stopped ) { this.stringHandler.handleString( (String)this.ois.readObject() ); } } catch (OptionalDataException ode) { throw new RuntimeException("Client: readObject() failed with OptionalDataException."); } catch (IOException e) { throw new RuntimeException("Client: failed to read"); } catch (ClassNotFoundException cnfe) { throw new RuntimeException("Client: readObject() failed with ClassNotFoundException."); } } /** * Use this method to send a String to the server. */ public void send( String s ) { try { this.oos.writeObject(s); } catch (IOException e) { throw new RuntimeException("Client: failed to send " + s); } } /** * Override default string handling behavior by providing a new * StringHandler. */ public void setStringHandler( StringHandler sh ) { this.stringHandler = sh; } /** * This method is passed the String which has been read by the Client * if no other StringHandler has been set. * * Specialize the client by providing an alternate StringHandler. */ public void handleString( String s ) { System.out.println("Client: Got " + s); System.out.flush(); } /** * Closes the socket, stops the thread. */ public void finalize() { this.stopped = true; try { this.sock.close(); } catch (IOException e) {} } } /* Comments: * * History: * $Log: Client.java,v $ * Revision 1.1.1.1 2002/06/05 21:56:32 root * CS101 comes to Olin finally. * * Revision 1.8 1998/07/24 17:13:37 tparnell * Placate new javadoc behavior * * Revision 1.7 1998/07/22 22:10:32 tparnell * javadoc fix * * Revision 1.6 1998/07/22 18:17:49 tparnell * move from util to net * * Revision 1.5 1998/07/20 21:35:52 tparnell * Moved from Data*Stream to Object*Stream. * * Revision 1.4 1998/07/08 16:11:11 tparnell * update to JDK1.2: removed refrences to Thread.stop() since it has * deprecated. * * Revision 1.3 1998/06/24 21:26:31 tparnell * code cleanup * * Revision 1.2 1998/06/03 21:17:46 tparnell * update from Java 1.0 to 1.1 * * Revision 1.4 1996/11/18 16:41:17 las * Client, Server, their dependencies (e.g. the Dialogs and their * invokers) all work. ClientTester is a bit awkward in that it doesn't * echo received strings until something is read. Oh, well. * Moving them to cs101.util in the next revision. * * Revision 1.3 1996/11/17 22:28:12 las * Everything compiles (now). Client, Server, ClientDialog, ServerDialog, * StringHandler, and RunServer need to be moved to cs101.util. But * first, to test.... * * Revision 1.2 1996/11/17 21:26:52 las * Client, ClientDialog writen, not yet tested. * * Revision 1.1 1996/11/17 19:39:30 las * Intermediate state on the way to an application version. Some files * here actually belong in CS101. Otherwise, the general file structure * is correct, but the file contents are in some cases grossly out of * line. * * Desired structure: * SharedWhiteboardDemo runs the (client side of the) demo. * SharedWhiteboard is a helper file that starts things up correctly; * it's the class definition, though, not the main (which is in * SharedWhiteboardDemo). * NetScribbleData is ScribbleData that sets up a client connection. It * uses StringHandler and Client. * StringHandler, ClientDialog, ServerDialog, and maybe Client and Server * go in the cs101 package. StringHandler is the interface Client uses. * ClientDialog and ServerDialog are QueryDialogs specialized for * obtaining the appropriate information. Client and Server are pretty * generic (Server is a broadcaster and Client has send and * StringHandler.handleString.) * Fall 96, they write SharedWhiteboard(Demo), NetScribbleData, and * Client. * * Revision 1.5 1996/08/04 10:04:30 reuben * made PORT and SERVER private protected * * Revision 1.4 1996/08/01 18:26:16 reuben * More javadoc tweaking (hopefully the final pass) * * Revision 1.3 1996/08/01 01:56:33 reuben * Yesturday's changes were tested. * (I wonder if using cvs and $log$ creates a circular modifcation problem) * * Revision 1.2 1996/07/30 21:39:25 reuben * Changed the way the client decides which host and port to connect to: * Client looks for applet params. If undefiened or unusable, * Client uses a default port and connects to the server that the applet * was downloaded from. If using appletviewer, default is to connect to * the machine you are on. * Note: These changes have not yet been tested. * * Revision 1.1.1.1 1996/07/18 17:38:24 sit * Import from /mit/6.096/share/classes after 6.80s session * * Revision 1.1 1996/07/02 21:47:51 las * Initial revision * * */