📄 pooltcpconnector.java
字号:
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.service;
import org.apache.tomcat.util.*;
import org.apache.tomcat.core.*;
import org.apache.tomcat.net.*;
import org.apache.tomcat.logging.*;
import java.io.*;
import java.net.*;
import java.util.*;
//import org.apache.tomcat.server.HttpServer;
/* Similar with MPM module in Apache2.0. Handles all the details related with
"tcp server" functionality - thread management, accept policy, etc.
It should do nothing more - as soon as it get a socket ( and all socket options
are set, etc), it just handle the stream to ConnectionHandler.processConnection. (costin)
*/
/**
* Connector for a TCP-based connector using the API in tomcat.service.
* You need to set a "connection.handler" property with the class name of
* the TCP connection handler
*
* @author costin@eng.sun.com
* @author Gal Shachor [shachor@il.ibm.com]
* @author Arieh Markel [arieh.markel@sun.com]
*/
public final class PoolTcpConnector implements ServerConnector {
// Attributes we accept ( to support the old model of
// configuration, will be deprecated )
public static final String VHOST_PORT="vhost_port";
public static final String VHOST_NAME="vhost_name";
public static final String VHOST_ADDRESS="vhost_address";
public static final String SOCKET_FACTORY="socketFactory";
public static final String INET = "inet";
public static final String PORT = "port";
public static final String HANDLER = "handler";
/*
* Threading and mod_mpm style properties.
*/
public static final String THREAD_POOL = "thread_pool";
public static final String MAX_THREADS = "max_threads";
public static final String MAX_SPARE_THREADS = "max_spare_threads";
public static final String MIN_SPARE_THREADS = "min_spare_threads";
public static final String BACKLOG = "backlog";
// XXX define ConnectorException
// XXX replace strings with sm.get...
// XXX replace static strings with constants
String handlerClassName;
PoolTcpEndpoint ep;
TcpConnectionHandler con;
Hashtable attributes = new Hashtable();
Object cm;
private LogHelper loghelper = new LogHelper("tc_log", "PoolTcpConnector");
private String vhost;
private InetAddress address;
private int port;
private int backlog = -1;
private boolean usePools = true;
private int maxThreads = -1;
private int maxSpareThreads = -1;
private int minSpareThreads = -1;
private ServerSocketFactory socketFactory;
private ServerSocket serverSocket;
boolean running = true;
int debug=0;
public PoolTcpConnector() {
ep = new PoolTcpEndpoint();
}
// -------------------- Start/stop --------------------
public void start() throws Exception {
if(con==null)
throw new Exception( "Invalid ConnectionHandler");
con.setServer( cm );
con.setAttribute("context.manager",cm ); // old mechanism
// Pass properties to the handler
Enumeration attE=attributes.keys();
while( attE.hasMoreElements() ) {
String key=(String)attE.nextElement();
Object v=attributes.get( key );
con.setAttribute( key, v );
}
ep.setPort(port);
ep.setAddress( address );
ep.setPoolOn(usePools);
if(backlog > 0) {
ep.setBacklog(backlog);
}
if(maxThreads > 0) {
ep.setMaxThreads(maxThreads);
}
if(maxSpareThreads > 0) {
ep.setMaxSpareThreads(maxSpareThreads);
}
if(minSpareThreads > 0) {
ep.setMinSpareThreads(minSpareThreads);
}
if(socketFactory != null) {
ep.setServerSocketFactory( socketFactory );
// Pass properties to the socket factory
attE=attributes.keys();
while( attE.hasMoreElements() ) {
String key=(String)attE.nextElement();
Object v=attributes.get( key );
socketFactory.setAttribute( key, v );
}
}
ep.setConnectionHandler( con );
ep.startEndpoint();
String classN=con.getClass().getName();
int lidot=classN.lastIndexOf( "." );
if( lidot >0 ) classN=classN.substring( lidot + 1 );
loghelper.log("Starting " + classN + " on " + port);
}
public void stop() throws Exception {
ep.stopEndpoint();
}
// -------------------- Tcp-server specific methods --------------------
public void setTcpConnectionHandler( TcpConnectionHandler handler) {
this.con=handler;
}
public TcpConnectionHandler getTcpConnectionHandler() {
return con;
}
// -------------------- Bean-setters for TcpConnector --------------------
public void setServer( Object ctx ) {
this.cm=ctx;
}
public void setDebug( int i ) {
debug=i;
}
public void setPort( int port ) {
this.port=port;
}
public void setPort( String portS ) {
this.port=string2Int( portS );
}
public int getPort() {
return port;
}
/** Generic configure system - this allows Connector
* configuration using name/value.
*
* The "preferred" configuration is to call setters,
* and tomcat using server.xml will do that, but
* this allows (minimal) integration with simpler
* systems.
*
* Only a minimal number of properties can be set
* this way. This mechanism may be deprecated
* after we improve the startup system.
*
* Supported attributes:
* "port" - port
* "handler" - class implementing ConnectionHandler
* "thread_pool" - whether thread pools are being used
* "max_threads" - maximum number of threads in pool
* "max_spare_threads" - maximum number of threads in pool
* "min_spare_threads" - minimum number of threads in pool
* "backlog" - the backlog value for the network connections
* "vhost_port" - port ( will act as a virtual host )
* "vhost_name" - virtual host name
* "vhost_address" - virtual host binding address
* "socketFactory" - socket factory - for ssl.
*
* Note that the attributes are passed to the Endpoint.
*
* @param prop the name of the property whose value is being set
* @param value the value set on the property passed
*/
public void setAttribute( String prop, Object value) {
if( debug > 0 )
loghelper.log( "setAttribute( " + prop + " , " + value + ")");
try {
if( value instanceof String ) {
String valueS=(String)value;
if( PORT.equals(prop) ) {
setPort( valueS );
} else if(HANDLER.equals(prop)) {
con=string2ConnectionHandler( valueS );
} else if(THREAD_POOL.equals(prop)) {
usePools = ! valueS.equalsIgnoreCase("off");
} else if(INET.equals(prop)) {
address=string2Inet( valueS );
} else if( MAX_THREADS.equals(prop)) {
maxThreads = string2Int(valueS);
} else if( MAX_SPARE_THREADS.equals(prop)) {
maxSpareThreads = string2Int(valueS);
} else if( MIN_SPARE_THREADS.equals(prop)) {
minSpareThreads = string2Int(valueS);
} else if(VHOST_NAME.equals(prop) ) {
vhost=valueS;
} else if( BACKLOG.equals(prop)) {
backlog = string2Int(valueS);
} else if(VHOST_PORT.equals(prop) ) {
port= string2Int( valueS );
} else if(SOCKET_FACTORY.equals(prop)) {
socketFactory= string2SocketFactory( valueS );
} else if(VHOST_ADDRESS.equals(prop)) {
address= string2Inet(valueS);
} else {
if( valueS!=null)
attributes.put( prop, valueS );
}
} else {
// Objects - avoids String-based "serialization"
if(VHOST_PORT.equals(prop) ) {
port=((Integer)value).intValue();
} else if(VHOST_ADDRESS.equals(prop)) {
address=(InetAddress)value;
} else if(SOCKET_FACTORY.equals(prop)) {
socketFactory=(ServerSocketFactory)value;
} else {
if( value!=null)
attributes.put( prop, value );
}
}
}
catch (Exception e) {
loghelper.log("setAttribute: " +prop + "=" + value, e, Logger.ERROR);
}
}
/** set the property passed with the value passed as argument
*
* @param prop the name of the property being set
* @param value the value to set the property to.
*/
public void setProperty( String prop, String value) {
setAttribute( prop, value );
}
/** Method returning the values of the attributes
*
* (NOTE: primitive types - int, boolean - are wrapped in appropriate
* classes - Integer, Boolean)
*
* Supported attributes:
* "port" - returns an Integer (bound port number)
* "handler" - returns reference to object implementing ConnectionHandler
* "thread_pool" - returns a Boolean (whether thread pools are used)
* "max_threads" - returns an Integer (maximum number of threads in pool)
* "max_spare_threads" - returns an Integer (maximum number of spare
* threads in pool)
* "min_spare_threads" - returns an Integer (minimum number of spare
* threads in pool
* "backlog" - returns an Integer (backlog value for the network
* connections)
* "vhost_port" - returns an Integer (port)
* "vhost_name" - returns a String with the virtual host name
* "vhost_address" - returns an InetAddress (virtual host bound address)
* "socketFactory" - returns a ServerSocketFactory
*
* @param prop the property whose value is looked for
*
* @return an Object that corresponds to the value requested
*/
public Object getAttribute( String prop ) {
if( debug > 0 )
loghelper.log( "getAttribute( " + prop + ")");
try {
if( PORT.equals(prop) ) {
return new Integer(port);
} else if(HANDLER.equals(prop)) {
return con;
} else if(THREAD_POOL.equals(prop)) {
return new Boolean(usePools);
} else if(INET.equals(prop)) {
return address;
} else if( MAX_THREADS.equals(prop)) {
return new Integer(maxThreads);
} else if( MAX_SPARE_THREADS.equals(prop)) {
return new Integer(maxSpareThreads);
} else if( MIN_SPARE_THREADS.equals(prop)) {
return new Integer(minSpareThreads);
} else if(VHOST_NAME.equals(prop) ) {
return vhost;
} else if( BACKLOG.equals(prop)) {
return new Integer(backlog);
} else if(VHOST_PORT.equals(prop) ) {
return new Integer(port);
} else if(SOCKET_FACTORY.equals(prop)) {
return socketFactory;
} else if(VHOST_ADDRESS.equals(prop)) {
return address;
} else {
return attributes.get (prop);
}
}
catch (Exception e) {
loghelper.log("getAttribute: " +prop, e, Logger.ERROR);
}
return null;
}
/**
* Set a logger explicitly. Note that setLogger(null) will not
* necessarily redirect log output to System.out; if there is a
* "tc_log" logger it will default back to using it.
**/
public void setLogger( Logger logger ) {
loghelper.setLogger(logger);
}
/**
* Set a socket factory explicitly. This is used
* by the EmbededTomcat class to create custom endpoints.
*/
public void setSocketFactory(ServerSocketFactory socketFactory) {
this.socketFactory = socketFactory;
}
// -------------------- Implementation methods --------------------
// now they just throw exceptions, which are caught and logged by
// the caller
private static TcpConnectionHandler string2ConnectionHandler( String val) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class chC=Class.forName( val );
return (TcpConnectionHandler)chC.newInstance();
}
private static ServerSocketFactory string2SocketFactory( String val) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class chC=Class.forName( val );
return (ServerSocketFactory)chC.newInstance();
}
private static InetAddress string2Inet( String val) throws UnknownHostException {
return InetAddress.getByName( val );
}
private static int string2Int( String val) {
return Integer.parseInt(val);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -