//
// SocketSlaveDisplay.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

package visad;

import java.awt.Component;
import java.awt.event.MouseEvent;
import java.net.*;
import java.io.*;
import java.rmi.RemoteException;
import java.util.*;
import visad.browser.*;

/** A SocketSlaveDisplay server wraps around a VisAD display, providing support
    for stand-alone remote displays (i.e., not dependent on the VisAD packages)
    that communicate with the server using sockets. For an example, see
    examples/Test68.java together with the stand-alone VisAD applet
    visad.browser.VisADApplet, usable from within a web browser. */
public class SocketSlaveDisplay implements RemoteSlaveDisplay {

  /** debugging flag */
  private static final boolean DEBUG = false;

  /** the default port for server/client communication */
  private static final int DEFAULT_PORT = 4567;

  /** list of control classes that support socket-based collaboration */
  private static final Class[] supportedControls = {
    GraphicsModeControl.class, ContourControl.class
  };

  /** the port at which the server communicates with clients */
  private int port;

  /** the server's associated VisAD display */
  private DisplayImpl display;

  /** flag that prevents getImage() calls from signaling a FRAME_DONE event */
  private boolean flag;

  /** array of image data extracted from the VisAD display */
  private byte[] pix;

  /** height of image */
  private int h;

  /** width of image */
  private int w;

  /** the server's associated socket */
  private ServerSocket serverSocket;

  /** vector of client sockets connected to the server */
  private Vector clientSockets = new Vector();

  /** vector of client sockets' input streams */
  private Vector clientInputs = new Vector();

  /** vector of client sockets' output streams */
  private Vector clientOutputs = new Vector();

  /** vector of client socket ids */
  private Vector clientIds = new Vector();

  /** thread monitoring incoming clients */
  private Thread connectThread = null;

  /** thread monitoring communication between server and clients */
  private Thread commThread = null;

  /** whether the server is still alive */
  private boolean alive = true;

  /** next available client ID number */
  private int clientID = 0;

  /** this socket slave display */
  private final SocketSlaveDisplay socketSlave = this;

  /** contains the code for monitoring incoming clients */
  private Runnable connect = new Runnable() {
    public void run() {
      while (alive) {
        try {
          // wait for a new socket to connect
          Socket socket = serverSocket.accept();
          if (!alive) break;
          if (socket != null) {
            synchronized (clientSockets) {
              // add client to the list
              clientSockets.add(socket);

              // add client's input and output streams to the list
              DataInputStream in =
                new DataInputStream(socket.getInputStream());
              clientInputs.add(in);
              DataOutputStream out =
                new DataOutputStream(socket.getOutputStream());
              clientOutputs.add(out);

              // assign client an ID number
              out.writeInt(++clientID);
              clientIds.add(new Integer(clientID));
            }
          }
        }
        catch (IOException exc) {
          if (DEBUG) exc.printStackTrace();
        }
      }
    }
  };

  /** contains the code for monitoring server/client communication */
  private Runnable comm = new Runnable() {
    public void run() {
      while (alive) {
        boolean silence = true;
        Object[] sockets, inputs, outputs, cids;
        synchronized (clientSockets) {
          sockets = clientSockets.toArray();
          inputs = clientInputs.toArray();
          outputs = clientOutputs.toArray();
          cids = clientIds.toArray();
        }
        for (int i=0; i 0) {
              silence = false;
              // receive the client data
              int sid = in.readInt();
              if (DEBUG && sid != cid) {
                System.err.println("Warning: client #" + cid + " believes " +
                  "its ID number is " + sid);
              }
              int eventType = in.readInt();

              if (eventType == VisADApplet.REFRESH) {
                // send latest display image to the client
                updateClient(socket, in, out);

                // send latest supported control states to the client
                for (int j=0; j 0) {
          socket = (Socket) clientSockets.elementAt(0);
          in = (DataInputStream) clientInputs.elementAt(0);
          out = (DataOutputStream) clientOutputs.elementAt(0);
        }
      }
      if (socket == null) break;
      else killSocket(socket, in, out);
    }

    // shut down server socket
    try {
      serverSocket.close();
    }
    catch (IOException exc) {
      if (DEBUG) exc.printStackTrace();
    }
  }

}


 

Ads help maintain this website.