001    /*
002     * cs101.net.BabySitter.java
003     * $Id: BabySitter.java,v 1.2 2003/09/23 15:18:08 gus Exp $
004     *
005     * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group.
006     * For more information, see <a href="http://www.ai.mit.edu/projects/cs101/">the
007     * CS101 homepage</a> or email <las@ai.mit.edu>.
008     *
009     * Copyright (C) 1998 Massachusetts Institute of Technology.
010     * Please do not redistribute without obtaining permission.
011     */
012    
013    package cs101.net;
014    
015    import java.io.*;
016    import java.net.*;
017    
018    /**
019     * This object handles the io between the server and one client.
020     * It has a run method that listens for information and relays it to
021     * the server.   It also has a method to send information back to its client.
022     *
023     * <P>Copyright 1998 Massachusetts Institute of Technology
024     *
025     * @author Todd C. Panrell, tparnell@ai.mit.edu
026     * @version $Id: BabySitter.java,v 1.2 2003/09/23 15:18:08 gus Exp $
027     *
028     */
029    public class BabySitter implements Runnable {
030    
031      /** Server this client is connected to */
032      protected Server server;
033      /** Animacy that runs this object */
034      protected Thread spirit;
035    
036      /** Client connection */
037      protected Socket sock;
038      /** Where to read from client */
039      protected ObjectInputStream ois;
040      /** Where to write to client */
041      protected ObjectOutputStream oos;
042    
043      /** Flag to indicate whether the Thread animating this should stop */
044      private boolean stopped;
045    
046      /** 
047       * Creates a BabySitter to handle communication with a 
048       * client.  Spawns a new thread to handle input from client;
049       * sends strings on request.
050       * 
051       * @param sock the client socket of this threads client
052       * @param server The <code>Server</code> object for this BabySitter
053       *
054       * @see #send
055       * @see Server#sendToAllExcept
056       */
057      protected BabySitter(Socket sock, Server server) {
058        System.out.println( "Server:  setting up new connection from " +
059                            sock.getInetAddress().getHostName() +
060                            " on port " + sock.getPort() );
061        this.sock = sock;
062        this.server = server;
063        try {
064          // it is very, very important to create the Output before Input
065          this.oos = new ObjectOutputStream(sock.getOutputStream());
066          this.ois = new ObjectInputStream(sock.getInputStream());
067        } catch (IOException e) {
068          try { this.sock.close(); } catch ( IOException e2 ) {}
069          System.out.println("Server:  socket error in BabySitter");
070          this.server.removeBabySitter(this);
071          return;
072        }
073        this.spirit = new Thread( this );
074        this.spirit.start();
075      }
076    
077      /**
078       * Sends a String to the client.
079       *
080       * @param s the String to send
081       */
082      protected void send(String s) {
083        try {
084          //            System.out.println("Server:  sending "+s);
085          this.oos.writeObject(s);
086          //            System.out.println("Server:  successfully sent "+s);
087        } catch (IOException e) {       
088          System.out.println("Server:  socket error in send");
089          this.server.removeBabySitter(this);
090        }
091      }
092    
093      /** 
094       * Recieves new info from clients.
095       *
096       * @see Server#sendToAllExcept
097       */
098      public void run() {
099        System.out.println("Server:  BabySitter running");
100        while( !this.stopped )
101          {
102            try {
103              String s = (String)ois.readObject();
104              System.out.println( "Server:  just read '" + s +"' from " +
105                                  this.sock.getInetAddress().getHostName() +
106                                  ", port " + this.sock.getPort() );
107    
108              if( s == null || s == "" ) {
109                this.server.removeBabySitter(this);
110                return;
111              }
112              this.server.sendToAllExcept(s,this);
113                    
114            } catch (IOException e) {
115              System.out.println("Server:  socket error in run ");
116              this.server.removeBabySitter(this);
117            } catch (ClassNotFoundException cnfe) {
118              System.out.println("Server:  could not find class String.");
119              this.server.removeBabySitter(this);
120            }
121            
122          }
123      }
124    
125      /**
126       * Should only be called by Server.
127       * User server.removeBabySittter( BabySitter ) instead.
128       *
129       * @see Server#removeBabySitter
130       */
131      protected void stop() {
132        System.out.println( "Server:  closing connection from " +
133                            this.sock.getInetAddress().getHostName() +
134                            " on port " + this.sock.getPort() );
135        try {
136          this.ois.close();
137        } catch (IOException e) {}
138        
139        try {
140          this.oos.close();
141        } catch (IOException e) {}
142    
143        try {
144          this.sock.close();
145        } catch (IOException e) {}
146    
147        this.stopped = true;
148      }         
149    }
150    
151    /*
152     * $Log: BabySitter.java,v $
153     * Revision 1.2  2003/09/23 15:18:08  gus
154     * javadoc fix
155     *
156     * Revision 1.1.1.1  2002/06/05 21:56:32  root
157     * CS101 comes to Olin finally.
158     *
159     * Revision 1.7  1998/07/24 17:13:36  tparnell
160     * Placate new javadoc behavior
161     *
162     * Revision 1.6  1998/07/22 15:42:22  tparnell
163     * moved to cs101.net
164     *
165     * Revision 1.5  1998/07/20 21:35:50  tparnell
166     * Moved from Data*Stream to Object*Stream.
167     *
168     * Revision 1.4  1998/07/08 16:11:49  tparnell
169     * update to JDK1.2: removed refrences to Thread.stop() since it has been
170     * deprecated in 1.2
171     *
172     * Revision 1.3  1998/06/24 21:24:27  tparnell
173     * added logging to file
174     *
175     */