|  | 
         
          |  
              The applet SimClient 
                shown below connects to the SimServer 
                program via a socket connection. The user enters the number of 
                drops to make and the sigma (standard deviation) on the smearing 
                of the position measurements of the mass as it drops.  Four buttons control the program. "Connect/Disconnect" 
                makes or breaks the connection to the server. "Exit" 
                ends the program when it runs in application mode. "Run 
                Sim" tells the server to start the simulation, and 
                "Clear" 
                will clear the data plots. 
              The host field at the top provides the address for the server. (It 
              defaults to 127.0.0.1  
              for the local machine.) The user name is used in the login with 
              the server. 
               The top plot shows the position versus time of each drop as the 
                data arrives. The bottom plot fits a quadratic polynomial to the 
                average position vs. time of all the drops. This fit produces 
                the value of the gravitational acceleration constant. (See Chapter 
                9: Physics for more about this simulation.)  
                
                   
                    | SimClient Application/Applet
 
  
                        SimClient.java 
                          - 
                          derived from the demonstration program Ch.9: 
                          Physics: DropTestAnalysisApplet. The mass drop classes 
                          became part of the server simulation. The fields at 
                          the top allow the user to enter the number of drops 
                          the simulator should execute and what smearing (std. 
                          dev.) should be made on the data points. When 
                          a connection is made to the sever, a SimClientWorker 
                          object is created to take care of all communications 
                          with the server.  The 
                          Drop Event plot shows data from each drop while the 
                          bottom plot fits a line through the average Y vs. time 
                          data. This fit provides the gravitational constant value 
                          shown at the bottom.  SimClientWorker.java 
                          - 
                          tends the socket connection to the server. Sends and 
                          obtains setup parameters, obtains the data from the 
                          simulator, and tells the SimClient when the run is finished. NetStreamMethods.java 
                           
                          - convenient utility class with methods for reading 
                          and writing over the socket streams. (Code on SimServer 
                          page.)  SimUtil.java 
                          - another convenience class that holds some constants 
                          used in the communications protocols. 
                          (Code on SimServer page.) 
                          
 + Previous classes:
 Ch. 
                          9: Physics: DropAnalyzer.java
 Ch. 
                          8: Physics: 
                          Fit.java, 
                          FitPoly.java, 
                          DrawPoly.java
 Ch. 
                          6: Tech:  
                          DrawPanel.java, 
                          DrawPoints.java, 
                          DrawFunction.java
 Ch. 
                          6: Tech: PlotPanel.java, 
                          PlotFormat.java
 
 |   
                    | package 
                      SimClientServer; 
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;
 import java.util.*;
 import java.io.*;
 import java.net.*;
 
 
 /**
 *
 *  A Client for a Prototype Remote 
                      Simulation System
 *
 *  SimClient controls a mass drop 
                      simulation run by SimServer. SimClient
 *  contacts the server and the server 
                      assigns a simulator to the client. The
 *  client in turn assigns a SimClientWorker 
                      to deal with the exchange of
 *  messages to set up the simulation 
                      and to get the data from the simulation.
 *
 *  SimClient runs both as a standalone 
                      app or in a browser web page.
 *
 *  The User Interface displays several 
                      items of interest:
 *
 *   - The host IP and username are 
                      displayed in TextFields and can be altered.
 *   - Disconnect/Connect button can 
                      interrupt and restart the connection.
 *   - Run Sim button tells the server 
                      to run the sim and begin sending the data
 *   - Text fields allow user to set 
                      the number of drops and the sigma error on
 *     the simulated drop 
                      measurements.
 *   - A label displays the status 
                      of the connection
 *   - A TextArea displays status messages 
                      for the client/server exchange
 *   - One histogram displays individual 
                      drop data.
 *   - The second histogram displays 
                      the average Y vs time and a fit to the
 *     curve. The parameters 
                      of the fitted curve provide the "g" value
 *     displayed in a TextField 
                      at the bottom.
 *
 *  The thread class SimClientWorker 
                      is used to send  requests for data
 *  and to read the data.
 *
 **/
 public class SimClient extends JApplet
 implements ActionListener
 {
 // GUI setup
 
 // Use a DrawPanel to draw the data for each 
                      event
 DrawPanel fDrawDataPanel;
 DrawPoints fDrawPoints;
 double [][] fDataPointsArray;
 
 // The DropAnalyzer will have its own panel 
                      and histogram.
 DropAnalyzer fDropAnalyzer;
 
 // UI components
 JLabel     fStatusLabel  ;
 JTextField fHostField    ;
 JTextField fUserNameField;
 JTextField fNumDropsField;
 JTextField fSigmaField   ;
 JTextArea  fMessageArea  ;
 
 // Flag for whether the applet is in a browser
 // or running via the main () below.
 boolean fInBrowser = true;
 
 //Buttons
 JButton fStartButton;
 JButton fClearButton;
 JButton fExitButton;
 JButton fRunSimButton;
 
 // Networking setup
 
 // Properties needed for the connection setup
 Socket  fServer;;
 SimClientWorker fSimClientWorker;
 Thread fSimClientThread;
 
 int fDataServerPort = 2222; // use 2222 as default
 String fClientPort;
 String fHost     = "127.0.0.1";
 String fUserName = "Smith";
 
 // Data setup
 // Amount of data in each set read from the 
                      server
 int fMaxDataMeasurements = 40;
 int fNumDrops  = 10;
 double fSigmaY = 1.0; // Smearing std.dev. for 
                      y positions
 double fTFrame = 0.020; // in secs
 
 // Dimensions for the drop area.
 double fYBallStart = 200.0; // cm
 double fYBallEnd   =   0.0; 
                      // cm
 
 // Range of the drop time.
 double fTStart = 0.00; // sec
 double fTEnd   = 0.75; // sec
 
 boolean fConnected = false; // flag for connection 
                      status
 String fMsgLine    = "";    // 
                      String displayed in status TextField
 String fDataLine   = "";    // 
                      String displayed in data TextArea
 
 int fTimeUpdate = 500; // read data every 500 
                      msecs
 
 // Arrays to hold setup parametes for the simulation.
 int    [] fISetup;
 double [] fDSetup;
 
 /** Create a User Interface with a textarea 
                      with scroll bars
 * and a Go button to initiate processing 
                      and a Clear button
 * to clear the textarea.
 **/
 public void init () {
 
 // Creat a DrawPoints instance and 
                      a DrawPanel panel
 // to display data points.
 fDrawPoints = new DrawPoints 
                      ();
 fDrawPoints.setSymbolType 
                      (DrawPoints.RECT);
 
 DrawFunction [] draw_functions 
                      = new DrawFunction[1];
 draw_functions[0] = 
                      fDrawPoints;
 fDataPointsArray = new 
                      double[4][];
 
 // Initially the points 
                      arrays are all null;
 fDrawPoints.setParameters 
                      (null, fDataPointsArray);
 
 fDrawDataPanel = new 
                      DrawPanel (fYBallEnd, fYBallStart,
 fTStart, 
                      fTEnd, draw_functions);
 
 fDrawDataPanel.setTitle 
                      ("Drop Event Data");
 
 // Create the analyzer.
 fDropAnalyzer = new 
                      DropAnalyzer (fYBallEnd, fYBallStart,
 fTStart, 
                      fTEnd);
 
 // Initialize the setup 
                      arrays. They are passed to the
 // server to set up 
                      the simulation.
 fISetup = new int[2];
 fISetup[0] = fNumDrops;
 fISetup[1] = fMaxDataMeasurements;
 
 fDSetup = new double[2];
 fDSetup[0] = fSigmaY;
 fDSetup[1] = fTFrame;
 
 // Get the DrawPanel 
                      from the analyzer
 JPanel drop_analyzer_panel 
                      = fDropAnalyzer.getPanel ();
 
 // Add the two data 
                      panels
 JPanel data_panels = 
                      new JPanel (new GridLayout (2,1));
 data_panels.add (fDrawDataPanel);
 data_panels.add (drop_analyzer_panel);
 
 
 // Control fields
 
 // First provide the 
                      inputs field for the host IP
 // and for the user 
                      name.
 fHostField = new JTextField 
                      (fHost,16);
 JLabel host_label = 
                      new JLabel ("Host: ");
 host_label.setHorizontalAlignment 
                      (SwingConstants.RIGHT);
 fUserNameField    = 
                      new JTextField (fUserName,16);
 JLabel name_label = 
                      new JLabel ("User Name: ");
 name_label.setHorizontalAlignment 
                      (SwingConstants.RIGHT);
 
 // Top line of controls 
                      = host and name inputs
 JPanel ctrls_panel1 
                      = new JPanel ();
 ctrls_panel1.add (host_label);
 ctrls_panel1.add (fHostField);
 ctrls_panel1.add (name_label);
 ctrls_panel1.add (fUserNameField);
 
 // Next line holds the 
                      buttons, and the data
 // channel number to 
                      monitor.
 fStartButton = new JButton 
                      ("Connect");
 fStartButton.addActionListener 
                      (this);
 fClearButton = new JButton 
                      ("Clear");
 fClearButton.addActionListener 
                      (this);
 fExitButton = new JButton 
                      ("Exit");
 if ( fInBrowser)
 fExitButton.setEnabled 
                      (false);
 else
 fExitButton.addActionListener 
                      (this);
 fRunSimButton = new 
                      JButton ("Run Sim");
 fRunSimButton.setEnabled 
                      (false);
 fRunSimButton.addActionListener 
                      (this);
 
 JPanel buttons_panel 
                      = new JPanel (new GridLayout (2,2));
 buttons_panel.add (fStartButton);
 buttons_panel.add (fClearButton);
 buttons_panel.add (fExitButton);
 buttons_panel.add (fRunSimButton);
 
 JLabel num_drops_label 
                      = new JLabel ("Num Drops");
 num_drops_label.setHorizontalAlignment 
                      (SwingConstants.CENTER);
 fNumDropsField = new 
                      JTextField (Integer.toString (fNumDrops),5);
 
 JLabel sigma_label = 
                      new JLabel ("Sigma");
 sigma_label.setHorizontalAlignment 
                      (SwingConstants.CENTER);
 fSigmaField = new JTextField 
                      (Double.toString (fSigmaY),5);
 
 JPanel inputs_panel 
                      = new JPanel (new GridLayout (2,2));
 inputs_panel.add (fSigmaField);
 inputs_panel.add (sigma_label);
 inputs_panel.add (num_drops_label);
 inputs_panel.add (fSigmaField);
 
 fStatusLabel = new JLabel 
                      ("DisfConnected");
 fStatusLabel.setForeground 
                      (Color.RED);
 fStatusLabel.setHorizontalAlignment 
                      (SwingConstants.CENTER);
 
 // Now pack the components 
                      of the second ctrls
 // line of components
 JPanel ctrls_panel2 
                      = new JPanel ();
 ctrls_panel2.add (buttons_panel);
 ctrls_panel2.add (inputs_panel);
 ctrls_panel2.add (fStatusLabel);
 
 // Put the 2 lines of 
                      controls into a sub-panel
 JPanel ctrls_panel12 
                      = new JPanel ();
 ctrls_panel12.add (ctrls_panel1);
 ctrls_panel12.add (ctrls_panel2);
 
 fMessageArea = new JTextArea 
                      ();
 fMessageArea.setEditable 
                      (false);
 // Add to a scroll pane 
                      so that a long list of
 // computations can 
                      be seen.
 JScrollPane area_scroll_pane 
                      = new JScrollPane (fMessageArea);
 
 // Use a GridBagLayout to apportion 
                      space for the
 // controls, text area and histograms.
 JPanel mainPanel = new JPanel (new 
                      GridBagLayout ());
 
 GridBagConstraints c = new GridBagConstraints 
                      ();
 c.fill = GridBagConstraints.BOTH;
 
 // Put ctrls at top
 c.gridx = 0;
 c.gridy = 0;
 c. weightx = 1.0;
 c. weighty = 0.05;
 mainPanel.add (ctrls_panel12,c);
 
 // Put text area below the controls
 c.gridx = 0;
 c.gridy = 1;
 c. weightx = 1.0;
 c. weighty = 0.25;
 mainPanel.add (area_scroll_pane, 
                      c);
 
 // Put histograms in rest of the 
                      vertical space
 c.gridx = 0;
 c.gridy = 2;
 c. weightx = 1.0;
 c. weighty = 0.70;
 c.insets = new Insets (2,2,10,2);
 mainPanel.add (data_panels, c);
 
 // Add text area with scrolling 
                      to the contentPane.
 add (mainPanel);
 
 } // init
 
 /** Respond to the buttons. **/
 public void actionPerformed (ActionEvent e)  {
 Object source = e.getSource ();
 if (source == fStartButton) {
 if ( fStartButton.getText 
                      ().equals ("Connect"))
 start 
                      ();
 else
 stop 
                      ();
 }
 else if (source == fRunSimButton) 
                      {
 initExpt 
                      ();
 fSimClientWorker.startRun 
                      (fISetup,fDSetup);
 fRunSimButton.setEnabled 
                      (false);
 fStartButton.setEnabled 
                      (false);
 }
 else if (source == fClearButton) 
                      {
 // Clear 
                      the data points display
 fDataPointsArray[0] 
                      = null;
 fDrawPoints.setParameters 
                      (null, fDataPointsArray);
 
 // Reset 
                      the analysis display.
 fDropAnalyzer.reset 
                      ();
 repaint 
                      ();
 }
 else if (source == fExitButton  && 
                      !fInBrowser){// Exit button
 fSimClientWorker.finish 
                      ();
 System.exit 
                      (0);
 }
 } // actionPerformed
 
 /**
 * Make the connection to the server. 
                      Set up the DataReader
 * and begin recording the data from 
                      the server.
 **/
 public void start () {
 // End the current connection if 
                      already fConnected.
 if  ( fConnected) stop 
                      ();
 
 // Now try to connect to the DataServer
 try {
 if (!connect ()) {
 
 println 
                      ("* NOT CONNECTED *");
 fStatusLabel.setText 
                      ("DisfConnected");
 fStatusLabel.setForeground 
                      (Color.RED);
 }
 }
 catch  (IOException e){
 println ("* NOT CONNECTED 
                      *");
 fStatusLabel.setText 
                      ("DisfConnected");
 fStatusLabel.setForeground 
                      (Color.RED);
 }
 } // start
 
 /**
 *  Connect to the server 
                      via a socket. Throws IOException
 *  if socket connection 
                      fails.
 **/
 boolean connect () throws IOException {
 
 // Get the current values of the 
                      host IP address and
 // and the username. These can't 
                      change after the connection
 // is made;
 fHost = fHostField.getText ();
 fUserName = fUserNameField.getText 
                      ();
 
 println ("Attempting to connect 
                      to server ...");
 
 try {
 // Connect to the DataHost 
                      using the host IP address
 // and the port at 
                      the server location
 fServer = new Socket 
                      (fHost, fDataServerPort);
 }
 catch (SecurityException se){
 println ("Security 
                      Exception:\n"+se);
 return false;
 }
 
 println ("Server fConnected - create 
                      worker");
 
 // Create the worker to tend to 
                      this server
 fSimClientWorker = new SimClientWorker 
                      (this, fServer, fUserName);
 fSimClientThread = new Thread (fSimClientWorker);
 fSimClientThread.start ();
 
 return true;
 } // connect
 
 /**  Get ready for the running of 
                      the simulation. **/
 void initExpt () {
 // Clear the data points display
 fDataPointsArray[0] = null;
 fDrawPoints.setParameters (null, 
                      fDataPointsArray);
 
 // Get the current values of the 
                      host IP address and
 // and the username
 fHost = fHostField.getText ();
 fUserName = fUserNameField.getText 
                      ();
 try {
 fNumDrops = Integer.parseInt 
                      (fNumDropsField.getText ());
 fSigmaY   
                      = Double.parseDouble (fSigmaField.getText ());
 }
 catch (NumberFormatException ex) 
                      {
 println ("Bad field 
                      value");
 return;
 }
 
 // Tell the analyzer how many drops 
                      will be made and how many
 // measurements per drop.
 fDropAnalyzer.initRun (fNumDrops, 
                      fMaxDataMeasurements);
 
 // Reset the analyzer.
 fDropAnalyzer.reset ();
 
 // Put the new parameter values 
                      in the setup arrays
 // for passing to the simulation.
 fISetup[0] = fNumDrops;
 fDSetup[0] = fSigmaY;
 
 } // initExpt
 
 /**
 * Can change the scaling on the 
                      analsys chart to reflect
 * changes in the experiment setup.
 **/
 public void setExptParameters (double [] params) 
                      {
 
 fYBallEnd   = params[0];
 fYBallStart = params[1];
 fTStart     
                      = params[2];
 fTEnd       
                      = params[3];
 
 fDropAnalyzer.setScaleLimits (fYBallEnd, 
                      fYBallStart,
 fTStart, 
                      fTEnd);
 fDrawDataPanel.setScaleLimits (fYBallEnd, 
                      fYBallStart,
 fTStart, fTEnd);
 
 } //setExptParameters
 
 /** Stop the worker thread. **/
 public void stop () {
 // Disconnect and kill the fSimClientWorker 
                      thread
 println ("Stop worker");
 fSimClientWorker.finish ();
 setDisconnected ();
 } // stop
 
 /**
 * When connection made by the SimClientWorker, 
                      it calls back
 * to this method to let the parent 
                      know that.
 **/
 void setConnected () {
 
 // Can't change the host or username 
                      while the connection
 // is active
 fHostField.setEnabled (false);
 fUserNameField.setEnabled (false);
 
 // Set connect flag and set buttons 
                      button text
 fConnected = true;
 fStartButton.setText ("Disconnect");
 fRunSimButton.setEnabled (true);
 
 // Indicate fConnected status on 
                      the user interface
 fStatusLabel.setText ("Connected");
 fStatusLabel.setForeground (Color.BLUE);
 } // setConnected
 
 /**
 * When connection stopped, reset 
                      the user interface.
 * The SimClientWorker object calls 
                      this method in the parent
 * when the connection to the server 
                      is broken.
 **/
 void setDisconnected () {
 
 // Switch the buttons for restart
 fStartButton.setText ("Connect");
 fStartButton.setEnabled (true);
 fRunSimButton.setEnabled (false);
 fStatusLabel.setText ("Disconnected");
 fStatusLabel.setForeground (Color.RED);
 } // setDisfConnected
 
 /**
 *  The SimClientWorker 
                      passes the data array from the server here.
 *  Display the data set 
                      by packing a histogram.
 *
 *  Also, plot the distribution 
                      of one of the channels of the data.
 *  The channel number 
                      is given in the text field.
 **/
 void setData (double [][] data) {
 
 // First display the 
                      set of data. The setParameters () method
 // in DrawPoints need 
                      a 2-d array argument. Here
 // the top 2 arrays 
                      will be null since there are no errors
 // on the horizontal 
                      and vertical coords.
 fDataPointsArray[0] 
                      = data[0]; // time array
 fDataPointsArray[1] 
                      = data[1]; // position measurements
 
 // Display the position 
                      values in each
 fDrawPoints.setParameters 
                      (null, fDataPointsArray);
 fDrawDataPanel.repaint 
                      ();
 
 // Analyze data for 
                      each drop
 fDropAnalyzer.analyzeDrop 
                      (data[0], data[1], data[0].length);
 
 } // setData
 
 /** Run has finished. **/
 void runDone () {
 
 // Analyze the data collected from 
                      the set of drops.
 fDropAnalyzer.analyzeRun ();
 
 // Reset user interface
 fRunSimButton.setEnabled (true);
 fStartButton.setEnabled (true);
 repaint ();
 } // runDone
 
 
 /**
 * Convenience method for sending 
                      messages to the
 *  text area.
 **/
 public void println (String str) {
 fMessageArea.append (str +"\n");
 repaint ();
 }
 
 /** Run the program as an application. **/
 public static void main (String[] args) {
 //
 int frame_width=500;
 int frame_height=650;
 
 // Create standalone version
 SimClient applet = new SimClient 
                      ();
 applet.fInBrowser = false;
 applet.init ();
 
 // Following anonymous class used 
                      to close window & exit program
 JFrame f = new JFrame ("Simulation 
                      Clent");
 f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
 
 // Add applet to the frame
 f.getContentPane ().add ( applet);
 f.setSize (new Dimension (frame_width,frame_height));
 f.setVisible (true);
 }  // main
 
 }  // class SimClient
 |   
                    | package 
                      SimClientServer; 
 // Begun from StartJApplet11
 
 import java.io.*;
 import java.net.*;
 
 /**
 * SimClient creates this Runnable class to tend 
                      to the connection
 * to the experiment simulation server. It first 
                      sets up the streams via the
 * socket to the server and then does a login 
                      procedure.
 *
 * The SimClient presents the GUI to the user 
                      and holds the DropAnalysis
 * instance to examine the data from the simulation 
                      at the server. The instance
 * of SimClientWorker takes care of the communications 
                      with the server.
 *
 * After obtaining from the servers the parameters 
                      of the simulation, this
 * object sends the run setup info  (e.g. 
                      number of drops events to execute)
 * and then waits for the SimClient to invoke 
                      start the run.
 **/
 public class SimClientWorker extends NetStreamMethods
 implements Runnable
 {
 // Reference to the parent program that opens 
                      this worker.
 SimClient fClient;
 
 // Networking
 Socket fServer;
 String fUserName;
 
 // Miscellaneous array buffers and utility variables
 int [] fISetup;
 double [] fDSetup;
 double [][] fData = new double [2][];
 
 int fServerCmd = 0;
 boolean fKeepRunning = true;
 
 /**
 *  Receive the DataClient 
                      to provide with the data
 *  from the server.
 **/
 public SimClientWorker (SimClient c, Socket 
                      server, String userName) {
 fClient = c;
 fServer = server;
 fUserName = userName;
 } // ctor
 
 /**
 * Remain in a loop to monitor the 
                      I/O from the server.
 * Display the data.
 **/
 public void run () {
 
 fClient.println ("Begin communications 
                      with server...");
 
 // The socket connection was made 
                      by the caller, now
 // set up the streams and login 
                      to the server.
 try {
 if (!doConnection ()){
 fClient.println 
                      (" Connection/login failed");
 closeServer 
                      ();
 return;
 }
 }
 catch (IOException ioe) {
 fClient.println (" I/O 
                      exception with server:"+ ioe);
 return;
 }
 
 // Connection made so let parent 
                      SimClient know that
 fClient.setConnected ();
 
 // Obtain via the server the parameters 
                      that describe the simulated
 // experiment.
 if (!getSimExptParams ()) {
 closeServer 
                      ();
 return;
 }
 
 fClient.println ("Simulated experiment 
                      parameters read and installed.");
 
 int nVal = 0;
 
 // This loops until either the connection 
                      is broken or the
 // stop button or stop key is hit
 while (fKeepRunning) {
 // Pause here to wait 
                      for the parent to start the data
 // taking by invoking 
                      the startRun () method.
 waitForInstructions 
                      ();
 fClient.println (" Send 
                      the run setup...");
 
 // Send the run setup 
                      info to the server. This will
 // also initiate the 
                      start of the simulation.
 if (!sendRunSetup () 
                      ) break;
 
 fClient.println (" Successfully 
                      sent run setup.");
 fClient.println (" Now 
                      read drop data.");
 
 // Run started.  Now 
                      read data for each drop event
 while (true) {
 
 // Get 
                      a message from the server
 fServerCmd 
                      = readNetInputInt ();
 if (fFailedIO) 
                      {
 fClient.println 
                      (" Server read failed - receiving data");
 break;
 }
 // Either 
                      more data or end of run
 if (fServerCmd 
                      != SimUtil.EVENT_DATA) break;
 
 // Get more 
                      data
 nVal = readNetInputInt 
                      ();
 if (fFailedIO) 
                      {
 fClient.println 
                      (" Server read failed - array sizes");
 break;
 }
 
 // Read 
                      time measurements
 fData[0] 
                      = readNetInputDoubleArray (fData[0], nVal);
 if (fFailedIO) 
                      {
 fClient.println 
                      (" Server read failed - array 1");
 break;
 }
 
 // Read 
                      time measurements
 fData[1] 
                      = readNetInputDoubleArray (fData[1], nVal);
 if (fFailedIO) 
                      {
 fClient.println 
                      (" Server read failed - array 2");
 break;
 }
 
 // Pass 
                      drop data to parent for analysis
 fClient.setData 
                      (fData);
 }
 // All the drop events 
                      completed. Now do the
 // run analysis.
 fClient.runDone ();
 
 if (fFailedIO) break;
 }
 
 // Finished with this connection 
                      to the server simulation
 // so close everything and shut 
                      up shop.
 if (fServer != null) closeServer 
                      ();
 fClient.println ("disconnected");
 fClient.setDisconnected ();
 
 } // run
 
 /**
 *  Wait here until the 
                      parent invokes the
 *  startRun () method.
 **/
 synchronized void waitForInstructions () {
 // Wait for notifyAll in startRun 
                      method.
 try {
 wait ();
 }
 catch (Exception e) {}
 } // waitForInstructions
 
 /**
 *  Get the parameters 
                      for the simulated experiment.
 *  These will be used 
                      in the run analysis here.
 **/
 boolean getSimExptParams () {
 // Get the initialize command from 
                      the server
 fServerCmd = readNetInputInt ();
 if (fFailedIO){
 fClient.println 
                      (" Server read failed - command");
 return false;
 }
 
 if (fServerCmd != SimUtil.INIT) 
                      {
 fClient.println 
                      (" Did not receive INIT command from server. Break connection!");
 return false;
 }
 
 // Get the experiment parameters 
                      - top/bot y values, time range
 int nVal = readNetInputInt ();
 if (fFailedIO) {
 fClient.println 
                      (" Server read failed - array sizes");
 return false;
 }
 
 // Read time measurements
 fData[0] = readNetInputDoubleArray 
                      (fData[0], nVal);
 if (fFailedIO){
 fClient.println 
                      (" Server read failed - array 1");
 return false;
 }
 
 fClient.setExptParameters (fData[0]);
 return true;
 } // getSimExptParams
 
 /**
 *  Send the run setup 
                      information to the server
 *  in an integer array 
                      and a floating point array.
 *  This will initiate 
                      the start of the run simulation
 *  on the server.
 **/
 boolean sendRunSetup () {
 
 // Tell the server to begin the 
                      simulation process
 writeNetOutputInt (SimUtil.START);
 if (fFailedIO){
 fClient.println (" 
                      Server write failed - Start run");
 return false;
 }
 
 // Send the run setup data in two 
                      arrays. The setup values
 // include such items as the number 
                      of drops to simulate.
 
 // Start with the integer array 
                      size
 writeNetOutputInt (fISetup.length);
 if (fFailedIO){
 fClient.println 
                      (" Server write failed - setup array 1 size");
 return false;
 }
 
 // Send the array
 writeNetOutputIntArray (fISetup, 
                      fISetup.length);
 if ( fFailedIO){
 fClient.println 
                      (" Server write failed - setup array 1");
 return false;
 }
 
 // Start with the double array size
 writeNetOutputInt (fDSetup.length);
 if (fFailedIO){
 fClient.println 
                      (" Server write failed - setup array 2 size");
 return false;
 }
 
 // Send the array
 writeNetOutputDoubleArray (fDSetup, 
                      fDSetup.length);
 if (fFailedIO){
 fClient.println 
                      (" Server write failed - setup array 2");
 return false;
 }
 return true;
 } // sendRunSetup
 
 /**
 * The parent SimClient_JApplet11 
                      invokes this when the
 * "Run Sim" button pushed. It will 
                      get the setup parameters
 * from the parent interface and 
                      with the invocation of
 * notifyAll () it will release the 
                      thread from the wait state.
 * This will start the simulation 
                      and transmission of the data
 * to here.
 **/
 public synchronized void startRun (int [] iData,
 double [] dData) {
 fISetup = iData;
 fDSetup = dData;
 notifyAll ();
 fClient.println (" Invoked startRun 
                      method");
 } // startRun
 
 /** Set up the streams with the server and then 
                      login. **/
 boolean doConnection () throws IOException {
 
 // Something wrong and server closed 
                      prematurely, causing reference
 // to be set to null
 if (fServer == null) {
 fClient.println 
                      (" Server prematurely closed.");
 return false;
 }
 
 // Get the input and output streams 
                      from the socket
 fNetInputStream = fServer.getInputStream 
                      ();
 
 // Use the reader for obtaining 
                      text
 fNetInputReader = new BufferedReader 
                      (
 new InputStreamReader 
                      ( fNetInputStream ) ) ;
 
 // User the DataInputStream for 
                      getting numerical values.
 fNetDataInputStream = new DataInputStream 
                      ( fNetInputStream );
 
 // Output stream for sending messages 
                      to the server.
 fNetOutputStream = fServer.getOutputStream 
                      ();
 
 // Get a data output stream for 
                      writing numerical data to the client
 fNetDataOutputStream = new DataOutputStream 
                      (fNetOutputStream);
 
 // Write with a PrintWriter for 
                      sending text to the server.
 fPrintWriter= new PrintWriter (
 new OutputStreamWriter 
                      (fNetDataOutputStream, "8859_1"), true );
 
 // Now try the login procedure.
 if (!login ()) return false;
 
 return true;
 
 } // doConnection
 
 /**
 * Here is a homemade login protocol. 
                      A password could
 * easily be added.
 **/
 boolean login () {
 fClient.println (" Waiting for login 
                      prompt...");
 
 String msg_line=readNetInputLine 
                      ();
 if (msg_line == null) return false;
 fClient.println (msg_line);
 if (!msg_line.startsWith ("Username:") 
                      ) return false;
 
 fClient.println (" Send username 
                      " + fUserName);
 writeNetOutputLine (fUserName);
 if (fFailedIO){
 fClient.println (" Error 
                      occurred in sending username!");
 return false;
 }
 
 fClient.println ("Waiting for response...");
 
 msg_line=readNetInputLine ();
 if (msg_line == null){
 fClient.println 
                      (" Error occurred in confirmation of login!");
 return false;
 }
 fClient.println (msg_line);
 
 return true;
 } // login
 
 /**
 * Do all of the steps needed to 
                      stop the connection.
 * This method can be invoked from 
                      the parent to kill
 * this worker and its server connection.
 **/
 public void finish () {
 // Kill the thread and stop the 
                      server
 fKeepRunning = false;
 closeServer ();
 } // finish
 
 /** Close the socket to the server. **/
 void closeServer () {
 fClient.println ("Close connection 
                      to server");
 fClient.setDisconnected ();
 if (fServer == null) return;
 try {
 fServer.close ();
 fServer = null;
 }
 catch (IOException e)
 {}
 } // closeServer
 
 } // class SimClientWorker
 |    Most recent update: Oct. 25, 
                2005 |  |  |