⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketclientfactory.java

📁 很棒的web服务器源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// SocketClientFactory.java// $Id: SocketClientFactory.java,v 1.44 2004/02/10 13:22:40 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.http.socket ;import java.io.IOException;import java.io.PrintStream;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import org.w3c.jigsaw.http.Client;import org.w3c.jigsaw.http.ClientFactory;import org.w3c.jigsaw.http.httpd;import org.w3c.jigsaw.config.PropertySet;import org.w3c.util.LRUAble;import org.w3c.util.LRUList;import org.w3c.util.ObservableProperties;import org.w3c.util.PropertyMonitoring;import org.w3c.util.Status;import org.w3c.util.SyncLRUList;import org.w3c.util.ThreadCache;class DebugThread extends Thread {    SocketClientFactory pool = null;    public void run() {	while ( true ) {	    try {		sleep(1000*10);		// Display some client statistics:		SocketClientState cs = null;		cs = (SocketClientState) pool.freeList.getHead();		while (cs != null) {		    System.out.println(cs.client				       + " reqcount="                                       + cs.client.getRequestCount()				       + ", bindcount="                                       + cs.client.getBindCount());		    cs = (SocketClientState)pool.freeList.getNext((LRUAble)cs);		}		System.out.println("freeCount ="+pool.freeCount);		System.out.println("idleCount ="+pool.idleCount);		System.out.println("totalCount="+pool.clientCount);		System.out.println("estimCount="+pool.clientEstim);		System.out.println("Average: "+pool.loadavg);	    } catch (Exception ex) {		ex.printStackTrace();	    }	}    }    DebugThread(SocketClientFactory pool) {	this.pool = pool;	setPriority(Thread.MAX_PRIORITY);    }}/** * The client pool is a kind of client factory. * Each time the server gets a new connection, it calls the client pool * to bound a client object (newly created or spared) to handle it. */public class SocketClientFactory implements ClientFactory, PropertyMonitoring,                                            Status {    private static final boolean debug       = false;    private static final boolean debugstats  = false;    private static final boolean debugthread = false;    public static final int MINSPARE_FREE = 5;    public static final int MAXSPARE_FREE = 10;    public static final int MAXSPARE_IDLE = 20;    public static final int MAXTHREADS    = 40;    public static final int MAXCLIENTS    = 32;    public static final int IDLETO        = 10000;    public static final int AVG_LIGHT = 1;    public static final int AVG_NORMAL = 2;    public static final int AVG_HIGH = 3;    public static final int AVG_DEAD = 4;    // FIXME doc    public final static String     MINSPARE_FREE_P = "org.w3c.jigsaw.http.socket.SocketClientFactory.minFree";    // FIXME doc    public final static String     MAXSPARE_FREE_P = "org.w3c.jigsaw.http.socket.SocketClientFactory.maxFree";    // FIXME doc    public final static String     MAXSPARE_IDLE_P = "org.w3c.jigsaw.http.socket.SocketClientFactory.maxIdle";    // FIXME doc    public final static String     MAXTHREADS_P = "org.w3c.jigsaw.http.socket.SocketClientFactory.maxThreads";    // FIXME doc    public final static String    MAXCLIENTS_P = "org.w3c.jigsaw.http.socket.SocketClientFactory.maxClients";    // FIXME doc    public final static String    IDLETO_P = "org.w3c.jigsaw.http.socket.SocketClientFactory.idleTimeout";    // FIXME doc    public final static String    BINDADDR_P = "org.w3c.jigsaw.http.socket.SocketClientFactory.bindAddress";    int minFree    = 0;    int maxFree    = 0;    int maxIdle    = 0;    int maxClients = 0;    InetAddress bindAddr = null;    int                  count     = 0 ;	// number of created clients.    httpd                server    = null ;    ObservableProperties props     = null ;    int                  busyCount = 0 ;	// number of busy clients.    LRUList idleList = null;    LRUList freeList = null;    SocketClientState csList = null;    int idleCount   = 0 ;    int freeCount   = 0 ;    int clientCount = 0 ;    int clientEstim = 0 ;    ThreadCache threadcache = null;    int loadavg = AVG_LIGHT;    boolean alive = true;    /**     * Give the status of this class as a partial HTML text which will be added     * into a block level element     * @return a String, the generated HTML     */    public String getHTMLStatus() {	int idle = 0;	int free = 0;	int used = 0;	int bndc = 0;	int reqc = 0;	int bnd, req;	StringBuffer sb = new StringBuffer();	SocketClientState cs = null;	StringBuffer sb1 = null;	if (debugstats) {	    sb1 = new StringBuffer();	}	// used clients	cs = csList;	if (debugstats) {	    sb1.append("<table border=\"1\" class=\"idle\">\n"		       + "<caption>Used Clients"		       +"</caption><tr><th>Id<th>BindCount<th>ReqCount<th>Diff"		       + "<th>BoundTo</tr>\n");	}	while (cs != null) {	    if (cs.status == SocketClientState.C_BUSY) {		InetAddress ia = cs.client.getInetAddress();		bnd = cs.client.getBindCount();		req = cs.client.getRequestCount();		if (debugstats) {		    sb1.append ("<tr><td>");		    sb1.append(cs.id);		    sb1.append("<td>");		    sb1.append(bnd);		    sb1.append("<td>");		    sb1.append(req);		    sb1.append("<td>");		    sb1.append(req - bnd);		    sb1.append("<td>");		    if (ia == null) {			sb1.append("Unbound");		    } else {			sb1.append(			          cs.client.getInetAddress().getHostAddress());		    }		    sb1.append("</tr>\n");		}		used++;		bndc += bnd;		reqc += req;	    }	    cs = cs.csnext;	}	if (debugstats) {	    sb1.append("</table>\n");	}	// idle clients	cs = (SocketClientState) idleList.getHead();	if (debugstats) {	    sb1.append("<table border=\"1\" class=\"idle\">\n<caption>Idle "		       +"Clients</caption><tr><th>Id<th>BindCount<th>ReqCount"		       +"<th>Diff<th>BoundTo</tr>\n");	}	while (cs != null) {	    InetAddress ia = cs.client.getInetAddress();	    idle++;	    bnd = cs.client.getBindCount(); 	    req = cs.client.getRequestCount(); 	    if (debugstats) {		sb1.append ("<tr><td>" +cs.id+ "<td>"+ bnd 			    + "<td>" + req + "<td>" + (req - bnd) + "<td>" + 			    ((ia == null) ? "Unbound" : 			     cs.client.getInetAddress().getHostAddress()) + 			    "</tr>\n" ); 	    }	    bndc += bnd; 	    reqc += req; 	    cs = (SocketClientState)idleList.getNext(cs);	}	if (debugstats) {	    sb1.append("</table>\n");	}	// free clients	cs = (SocketClientState) freeList.getHead();	if (debugstats) {	    sb1.append("<table border=\"1\" class=\"idle\">\n"		       + "<caption>Free Clients"		       + "</caption><tr><th>Id<th>BindCount<th>ReqCount<th>"		       + "Diff</tr>\n");	}	while (cs != null) {	    free++;	    bnd = cs.client.getBindCount();  	    req = cs.client.getRequestCount();  	    if (debugstats) {		sb1.append ("<tr><td>" + cs.id + "<td>"+ bnd			    + "<td>" + req + "<td>" + (req - bnd) + "\n");	    }	    bndc += bnd;	    reqc += req;	    cs = (SocketClientState)freeList.getNext(cs);	}	if (debugstats) {	    sb1.append("</table>\n");	}		// stats	sb.append("<table border class=\"thread\">\n<caption>Thread counts"		  + "</caption><tr><th>free<th>idle<th>used"		  + "<th>estim<th>total<th>Load</tr>");	sb.append("<tr><td>");	sb.append(freeCount);	sb.append('(');	sb.append(free);	sb.append(")</td><td>");	sb.append(idleCount);	sb.append('(');	sb.append(idle);	sb.append(")</td><td>");	sb.append(clientCount - freeCount - idleCount);	sb.append('(');	sb.append(used);	sb.append(")</td><td>");	sb.append(clientEstim);	sb.append("</td><td>");	sb.append(clientCount);	sb.append("</td><td>");	sb.append(loadavg);	sb.append("</td></tr></table>\n");	// usage stats	sb.append("<table border class=\"usage\">\n<caption>Usage</caption>"		  + "<tr><th>ReqCount<th>BindCount<th>Diff</tr>\n<tr><td>");	sb.append(reqc);	sb.append("</td><td>");	sb.append(bndc);	sb.append("</td><td>");	sb.append(reqc -bndc);	sb.append("</td></tr></table>\n");	if (debugstats) {	    sb.append(sb1);	}	if (debugstats) {	    cs = csList;	    sb.append("<table border=\"1\" class=\"idle\">\n<caption>General"		      + " Status</caption><tr><th>Id<th>Client<th>"		      + "Status<th>marked<th>Thread</tr>\n");	    while (cs != null) {		sb.append ("<tr><td>" +cs.id+ "<td>" + 			   ((cs.client == null) ? "None" : "bound") +			   "<td>" );		switch (cs.status) {		case SocketClientState.C_IDLE:		    sb.append ("Idle");		    break;		case SocketClientState.C_BUSY:		    sb.append ("Busy");		    break;		case SocketClientState.C_FREE:		    sb.append ("Free");		    break;		case SocketClientState.C_KILL:		    sb.append ("Kill");		    break;		case SocketClientState.C_FIN:		    sb.append ("Fin");		    break;		}		sb.append ("<td>" + cs.marked);		if (cs.client != null) {		    sb.append("<td>" + cs.client.thread +"</tr>\n");		} else {		    sb.append("<td>No CLient</tr>\n");		}		cs = cs.csnext;	    }	    sb.append("</table>\n");	}	return sb.toString();    }    /**     * Some property have changed, update our setting.     * @param name The name of the property that has changed.     * @return A boolean, <strong>true</strong> if we updated ourself      *    successfully.     */    public boolean propertyChanged (String name) {	httpd s = server;	if ( name.equals(MINSPARE_FREE_P) ) {	    minFree = props.getInteger(MINSPARE_FREE_P, minFree);	} else if ( name.equals(MAXSPARE_FREE_P) ) {	    maxFree = props.getInteger(MAXSPARE_FREE_P, maxFree);	} else if ( name.equals(MAXSPARE_IDLE_P) ) {	    maxIdle = props.getInteger(MAXSPARE_IDLE_P, maxIdle);	} else if ( name.equals(MAXTHREADS_P) ) {	    int maxThreads = props.getInteger(MAXTHREADS_P, -1);	    if ( maxThreads > 0 )		threadcache.setCachesize(maxThreads);	} else if ( name.equals(IDLETO_P) ) {	    int idleto = props.getInteger(IDLETO_P, -1);	    if ( idleto > 0 ) {		threadcache.setIdleTimeout(idleto);	    }	} else if ( name.equals(MAXCLIENTS_P) ) {	    int newmax = props.getInteger(MAXCLIENTS_P, -1);	    if ( newmax > maxClients ) {		for (int i = maxClients-newmax; --i >= 0; )		    addClient(true);	    } else if ( newmax > 0 ) {		maxClients = newmax;	    }	} else if (name.equals(BINDADDR_P)) {	    try {		bindAddr = InetAddress.getByName(props.getString(BINDADDR_P,								 null));	    } catch (Exception ex) {		// nothing	    }	}	return true ;    }    /**     * Remove this client state from the glohbal client list.     * @param cs The client state to remove from the list.     */    protected synchronized void deleteClient(SocketClientState cs) {	if ( cs.csprev == null ) {	    csList = cs.csnext;	} else if ( cs.csnext == null ) {	    cs.csprev.csnext = null;	} else {	    cs.csprev.csnext = cs.csnext;	    cs.csnext.csprev = cs.csprev;	}    }    /**     * Factory for creating a new client for this pool.     * @param server  the target http daemon      * @param state  the client state holder     * @return a new socket client     */    protected SocketClient createClient(httpd server, 					SocketClientState state) {	return new SocketClient(server, this, state);    }        /**     * Create a new client for this pool.     * @param free A boolean, if <strong>true</strong> the client is inserted     * straight into the free list, otherwise, it is not plugged into any     * list.     * @return A SocketClientState instance, if creation of a new client was     * allowed, <strong>null</strong> if no more clients could be created.     */    protected synchronized SocketClientState addClient (boolean free) {	// Create a new client. 	csList                   = new SocketClientState(csList);	SocketClientState cs     = csList;	SocketClient      client = createClient(server, cs);	cs.client = client;	clientCount++;	clientEstim++;	// Plug into free LRU if required:	if ( free ) {	    cs.status = SocketClientState.C_FREE;	    freeList.toHead(cs);	    freeCount++;	}	return cs ;    }    /**     * We are not using synchronized functions to speed up things,      * but it is sometime useful to check that clients are not in a bad     * shape     */    private final void checkDeadClients() {	SocketClientState cs = null;	cs = csList;	boolean check = true;	int idlecount = 0;	int freecount = 0;	int clientcount = 0;	while (cs != null) {	    if (cs.client != null) {		clientcount++;		switch(cs.status) {		case SocketClientState.C_BUSY:		    if (cs.client.thread == null) {			if (cs.marked) {			    if ( clientEstim <= maxClients ) {				cs.marked = false;				++freeCount;				updateLoadAverage();				freeList.toHead(cs);				cs.status = SocketClientState.C_FREE;				cs.client.done = true;			    } 			    check = false;			} else {			    cs.marked = true;			}		    }		    break;		case SocketClientState.C_FREE:		    freecount++;		    cs.marked = false;		    break;		default:		    cs.marked = false;		    break;		}	    }	    cs = cs.csnext;	}	// sanity check	if (freecount != freeCount) {	    cs = (SocketClientState) idleList.getHead();	    while (cs != null) {		idlecount++;		cs = (SocketClientState)idleList.getNext(cs);	    }	    cs = (SocketClientState) freeList.getHead();	    freecount = 0;	    while (cs != null) {		freecount++;		cs = (SocketClientState) freeList.getNext(cs);	    }	    freeCount = freecount;	    idleCount = idlecount;	}     }    /**     * Update our idea of the current load.     * The one important invariant here, is that whenever the free list     * becomes empty, then the load average should be equals to

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -