Package org.w3c.jigsaw.http.socket

Source Code of org.w3c.jigsaw.http.socket.SocketClient

// SocketClient.java
// $Id: SocketClient.java,v 1.25 2004/08/30 16:04:44 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.http.socket ;

import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintStream;

import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;

import org.w3c.jigsaw.http.Client;
import org.w3c.jigsaw.http.ClientException;
import org.w3c.jigsaw.http.httpd;

import org.w3c.tools.resources.ServerInterface;

/**
* This class implements the object that handles client connections.
* One such object exists per open connections at any given time.
* <p>The basic architecture is the following: the httpd instance accepts
* new connections on its port. When such a connection is accepted a Client
* object is requested to the client pool (which can implement what ever
* strategy is suitable). Each request is than managed by looking up an
*  resource and invoking the resource methods corresponding to the request.
* @see org.w3c.jigsaw.http.httpd
* @see org.w3c.jigsaw.http.Request
* @see org.w3c.jigsaw.http.Reply
*/

public class SocketClient extends Client implements Runnable {
    private static final boolean trace = false;

    /**
     * The ClientFactory that created this client.
     */
    private SocketClientFactory pool = null ;
    /**
     * The socket currently handled by the client.
     */
    protected Socket socket = null ;
    /**
     * Is this client still alive ?
     */
    protected boolean alive = false;
    /**
     * The client state for this client, has managed by the SocketClientFactory
     * @see SocketClientFactory
     */
    SocketClientState state = null;
    /**
     * Number of times this client was bound to a connection.
     */
    protected int bindcount = 0;
    /**
     * The thread that we have been attached to.
     */
    protected Thread thread = null;
    /**
     * Our reusable output buffer.
     */
    protected SocketOutputBuffer bufout = null;
    /**
     * Our we idle (waiting for next request ?)
     */
    protected boolean idle = false;

    /**
     * are we done?
     */
    protected boolean done = false;

    /**
     * Print that client into a String.
     * @return A String instance.
     */

    public String toString() {
  if ( thread != null )
      return "client-"+state.id+"("+thread.getName()+")";
  else
      return "client-"+state.id;
    }

    /**
     * If this client is allocated a thread, join it.
     */

    public void join() {
  if (thread != null) {
      while ( true ) {
    try {
        thread.join();
    } catch (InterruptedException ex) {
    }
      }
  }
    }

    /**
     * Run for our newly attached connection.
     * @return A boolean, <strong>true</strong> if the client is to be killed
     * as decided by its SocketClientFactory creator.
     */

    public void run() {
  thread = Thread.currentThread();
  if ( trace )
      System.out.println(this+": powered by "+thread);
  try {
      if ( bufout == null ) {
    // Make sure that buffer is a little smaller then the client
    // buffer. so writing to it will not copy it
    int bufsize = getServer().getClientBufferSize() - 1;
    bufout = new SocketOutputBuffer(socket.getOutputStream()
            , bufsize);
      } else {
    bufout.reuse(socket.getOutputStream());
      }
      startConnection(new BufferedInputStream(socket.getInputStream())
          , new DataOutputStream(bufout));
  } catch (IOException ex) {
      if ( debug )
    ex.printStackTrace();
  } catch (ClientException ex) {
      if ( debug )
    ex.printStackTrace();
      // Emit some debugging traces:
      if ( debug ) {
    if (ex.ex != null )
        ex.ex.printStackTrace() ;
    else
        ex.printStackTrace();
      }
      // If output is null, we have killed the connection...
      if ( alive && ! idle ) {
    error("caught ClientException: ["
                      + ex.getClass().getName()
          + "] " + ex.getMessage()) ;
      }
  } catch (Exception ex) {
      if (debug) {
    System.out.println("unknown exception caught in client run");
    ex.printStackTrace();
      }
  } finally {
      if ( ! pool.clientConnectionFinished(this) ) {
    pool.clientFinished(this);
      }
      thread = null;
  }
    }

    /**
     * Client implementation - Get the IP address of this client.
     * @return An InetAddress instance, or <strong>null</strong> if the
     * client is not currently running.
     */

    public InetAddress getInetAddress () {
  return (socket != null) ? socket.getInetAddress() : null;
    }

    /**
     * Client implementation - This connection has been stopped.
     * Make sure the whole socket is closed, and be ready to handle
     * next connection.
     */

    protected void stopConnection() {
  if ( trace )
      System.out.println(this+": stopConnection.");
  if ( socket != null ) {
      try {
    socket.close();
      } catch (Exception ex) {
      }
      socket = null;
//      alive = false;
//      if (!pool.idleClientRemove(this)) {
//    pool.clientFinished(this);
//      }
  }
    }

    /**
     * Get the thread powering that client.
     * @return A Thread instance, or <strong>null</strong>.
     */

    protected Thread getThread() {
  return thread;
    }

    /**
     * Client implementation - The current connection is idle.
     * The client is about to wait for the next request from the net, mark
     * it as idle to make it a candidate for persistent connection closing.
     * @return A boolean, if <strong>true</strong> our client factory wants
     * us to stop right now, in order to handle some other connection.
     */

    protected boolean idleConnection() {
  synchronized (state) {
      if ( trace )
    System.out.println(this+": idleConnection.");
      idle = true;
      return ! pool.notifyIdle(this);
  }
    }

    /**
     * Client implementation - The current connection is in use.
     * A request is about to be processed, mark that connection as used, to
     * remove it from the idle state.
     */

    protected void usedConnection() {
  synchronized (state) {
      if ( trace )
    System.out.println(this+": usedConnection.");
      idle = false;
      pool.notifyUse(this) ;
  }
    }

    /**
     * SocketClientFactory interface - Bind the socket to this client.
     * Binding a socket to a client triggers the processing of the underlying
     * connection. It is assumed that the client was ready to handle a new
     * connection before this method was called.
     * @param socket The socket this client should now handle.
     */

    protected synchronized void bind(Socket socket) {
  done = false;
  ServerInterface server = getServer();
  if ( trace )
      System.out.println(this+": bind.");
  this.socket = socket ;
        try {
//            socket.setSoTimeout(server.getRequestTimeOut());
      socket.setSoTimeout(pool.timeout);
        } catch (SocketException ex) {
      if (trace)
    ex.printStackTrace();
      server.errlog("Unable to set socket timeout!");
        }
  this.idle   = false;
  bindcount++;
  pool.run(this);
    }

    /**
     * SocketClientFactory interface - Unbind this client.
     * This client is handling an idle connection, unbind it to make
     * it free for handling some other more buzy connection.
     */

    protected synchronized void unbind() {
  if ( trace )
      System.out.println(this+": unbind.");
  interruptConnection(true);
    }

    /**
     * SocketClientFactory interface - Kill this client.
     * The clean way for our client factory to shut us down unconditionally.
     * This will free all resources acquired by this client, stop the current
     * connection processing if needed, and terminate the underlying thread.
     */

    protected synchronized void kill(boolean now) {
  if ( trace )
      System.out.println(this+": kill.");
  alive = false;
  interruptConnection(now);
    }

    /**
     * Get the total number of times this client was bound to a socket.
     * @return An integer, indicatingthe number of bind calls on this client.
     */

    public final int getBindCount() {
  return bindcount;
    }

    /**
     * Create an empty client, that will be ready to work.
     * The created client will run and wait for it to be <code>bind</code>
     * to some socket before proceeding.
     * @param server The server to which this client is attached.
     * @param id The client identifier.
     * @see org.w3c.jigsaw.http.Client
     * @see org.w3c.jigsaw.http.ClientFactory
     */

    protected SocketClient(httpd server,
         SocketClientFactory pool,
         SocketClientState state) {
  initialize(server, state.id);
  this.socket   = null ;
  this.pool     = pool;
  this.state    = state;
  this.alive    = true;
    }

}
TOP

Related Classes of org.w3c.jigsaw.http.socket.SocketClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.