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

📄 quickserver.java

📁 一个用java编写的服务器,对于学习网络编程的人来说是个很好的例子
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*
 * This file is part of the QuickServer library 
 * Copyright (C) QuickServer.org
 *
 * Use, modification, copying and distribution of this software is subject to
 * the terms and conditions of the GNU Lesser General Public License. 
 * You should have received a copy of the GNU LGP License along with this 
 * library; if not, you can download a copy from <http://www.quickserver.org/>.
 *
 * For questions, suggestions, bug-reports, enhancement-requests etc.
 * visit http://www.quickserver.org
 *
 */

package org.quickserver.net.server;

import java.io.*;
import java.net.*;

import org.quickserver.net.*;
//v1.1
import org.quickserver.net.qsadmin.*;
//v1.2
import java.util.logging.*;
//v1.3
import org.quickserver.util.pool.*;
import org.quickserver.util.pool.thread.*;
import org.apache.commons.pool.*;
import org.quickserver.util.xmlreader.*;
import org.quickserver.sql.*;
//v1.3.1
import java.util.*;
//v1.3.2
import org.quickserver.util.*;
import java.util.regex.*;
//v1.3.3
import org.quickserver.security.*;
//v1.4.0
import javax.net.ssl.*;
import javax.net.*;
import java.security.*;
import java.security.cert.*;
import org.quickserver.util.io.*;
//v1.4.5
import java.nio.*;
import java.nio.channels.*;
import org.quickserver.net.server.impl.*;

/**
 * Main class of QuickServer library. This class is used to create 
 * multi client servers quickly.
 * <p>
 * Ones a client is connected, it creates {@link ClientHandler} object, 
 * which is run using any thread available from the pool of threads 
 * maintained by {@link org.quickserver.util.pool.thread.ClientPool}, which 
 * handles the client. <br/>
 * QuickServer divides the application logic of its developer over eight 
 * class, <br>
 * 	<ul>
 *		<li>ClientEventHandler<br>
 * 		   &nbsp;Handles client events [Optional Class].
 * 		<li>ClientCommandHandler [#]<br>
 * 		   &nbsp;Handles client character/string commands.
 * 		<li>ClientObjectHandler [#]<br>
 * 		   &nbsp;Handles client interaction - Object commands.
 *		<li>ClientBinaryHandler [#]<br>
 * 		   &nbsp;Handles client interaction - binary data.
 *		<li>ClientWriteHandler [Optional Class]<br>
 * 		   &nbsp;Handles client interaction - writing data (Only used in non-blocking mode).
 * 		<li>ClientAuthenticationHandler [Optional Class]<br>
 * 			&nbsp;Used to Authencatet a client.
 * 		<li>ClientData [Optional Class]<br>
 * 			&nbsp;Client data carrier (support class)
 *		<li>ClientExtendedEventHandler [Optional Class]<br>
 * 		   &nbsp;Handles extended client events.
 * 	</ul>
 *
 * [#] = Any one of these have to be set based on default DataMode for input. 
 * The default DataMode for input is String so if not changes you will
 * have to set ClientCommandHandler.
 * </p>
 * <p>
 *  Eg:
 * <code><BLOCKQUOTE><pre>
package echoserver;

import org.quickserver.net.*;
import org.quickserver.net.server.*;

import java.io.*;

public class EchoServer {
	public static void main(String args[])	{
		String cmdHandle = "echoserver.EchoCommandHandler";
	
		QuickServer myServer = new QuickServer();
		myServer.setClientCommandHandler(cmdHandle);
		myServer.setPort(4123);
		myServer.setName(Echo Server v1.0");
		try {
			myServer.startServer();
		} catch(AppException e) {
			System.err.println("Error in server : "+e);
			e.printStackTrace();
		}
	}
}
</pre></BLOCKQUOTE></code></p>
 * 
 * @version 1.4.7
 * @author Akshathkumar Shetty
 */
public class QuickServer implements Runnable, Service, Cloneable, Serializable {
	//Some variable are not initialised to any value because the 
	//default java value was desired initial value. 

	//'dev ' = development build not yet final
	//'beta' = test build all features
	private final static String VER = "1.4.7";//change also in QSAdminMain
	private final static String NEW_LINE = "\r\n";

	static {
		System.out.print("Loading QuickServer v"+getVersion()+" ");
	}

	private String serverBanner;

	private String clientAuthenticationHandlerString; //v1.4.6
	private String clientEventHandlerString; //v1.4.6
	private String clientExtendedEventHandlerString; //v1.4.6
	private String clientCommandHandlerString;
	private String clientObjectHandlerString; //v1.2
	private String clientBinaryHandlerString; //v1.4
	private String clientWriteHandlerString; //v1.4.5
	private String clientDataString;
	
	private Authenticator authenticator;
	private ClientAuthenticationHandler clientAuthenticationHandler; //v1.4.6
	private ClientEventHandler clientEventHandler; //v1.4.6
	private ClientExtendedEventHandler clientExtendedEventHandler; //v1.4.6
	private ClientCommandHandler clientCommandHandler;
	private ClientObjectHandler clientObjectHandler; //v1.2
	private ClientBinaryHandler clientBinaryHandler; //v1.4
	private ClientWriteHandler clientWriteHandler; //v1.4.5
	private ClientData clientData;
	protected Class clientDataClass;

	private int serverPort = 9876;
	private Thread t; //Main thread
	private ServerSocket server;
	private String serverName = "QuickServer";
	private long maxConnection = -1;
	private int socketTimeout = 60 * 1000; //1 min socket timeout
	private String maxConnectionMsg = "-ERR Server Busy. Max Connection Reached";	
	private String timeoutMsg = "-ERR Timeout";
	private String maxAuthTryMsg = "-ERR Max Auth Try Reached";
	private int maxAuthTry = 5; //v1.2	

	static {
		System.out.print(".");
	}

	//--v1.1
	private InetAddress ipAddr;
	private boolean stopServer;
	private Object[] storeObjects;
	private QSAdminServer adminServer;

	//--v1.2
	//Logger for QuickServer
	private static final Logger logger = Logger.getLogger(QuickServer.class.getName());
	//Logger for the application using this QuickServer
	private Logger appLogger;

	//for Service interface
	private long suspendMaxConnection; //backup
	private String suspendMaxConnectionMsg; //backup
	private int serviceState = Service.UNKNOWN;

	static {
		System.out.print(".");
	}

	//--v1.3
	private QuickServerConfig config = new QuickServerConfig();
	private String consoleLoggingformatter;
	private String consoleLoggingLevel = "INFO";
	private ClientPool pool;
	private ObjectPool clientHandlerPool;
	private ObjectPool clientDataPool;
	private DBPoolUtil dBPoolUtil;

	//--v1.3.1
	private String loggingLevel = "INFO";

	//--v1.3.2
	private boolean skipValidation = false;
	private boolean communicationLogging = true;

	//--v1.3.3
	private String securityManagerClass;
	private AccessConstraintConfig accessConstraintConfig;
	private ClassLoader classLoader;
	private String applicationJarPath;
	private ServerHooks serverHooks;
	private ArrayList listOfServerHooks;

	static {
		System.out.print(".");
	}
	
	//--v1.4.0
	private Secure secure;
	private BasicServerConfig basicConfig = config;
	private SSLContext sslc;
	private KeyManager km[] = null;
	private TrustManager tm[] = null;
	private boolean runningSecure = false;
	private SecureStoreManager secureStoreManager = null;
	
	private Exception exceptionInRun = null;

	//--v1.4.5
	private ServerSocketChannel serverSocketChannel;
	private Selector selector;
	private boolean blockingMode = true;
	private ObjectPool byteBufferPool;
	private java.util.Date lastStartTime;
	private ClientIdentifier clientIdentifier;
	private GhostSocketReaper ghostSocketReaper;
	private PoolManager poolManager;
	private QSObjectPoolMaker qsObjectPoolMaker;

	//--v1.4.6
	private DataMode defaultDataModeIN = DataMode.STRING;
	private DataMode defaultDataModeOUT = DataMode.STRING;

	//-v1.4.7
	private Throwable serviceError;
	private Map registerChannelRequestMap;

	static {
		System.out.println(" Done");
		//should be commented if not a patch release
		//System.out.println("[Includes patch(#): t=152&p=532]");
		//should be commented if not a dev release
		//System.out.println("[Dev Build Date: Saturday, October 29, 2005]");
	}
	
	/** Returns the version of the library. */
	public static final String getVersion() {
		return VER;
	}

	/** 
	 * Returns the numerical version of the library.
	 * @since 1.2
	 */
	public static final float getVersionNo() {
		return getVersionNo(VER);
	}

	/** 
	 * Returns the numerical version of the library.
	 * @since 1.4.5
	 */
	public static final float getVersionNo(String ver) {
		//String ver = getVersion();
		float version = 0;
		int i = ver.indexOf(" "); //check if beta
		if(i == -1)
			i = ver.length();
		ver = ver.substring(0, i);
		
		i = ver.indexOf("."); //check for sub version
		if(i!=-1) {
			int j = ver.indexOf(".", i);
			if(j!=-1) {
				ver = ver.substring(0, i)+"."+
					MyString.replaceAll(ver.substring(i+1), ".", "");
			}
		}

		try	{
			version = Float.parseFloat(ver);	
		} catch(NumberFormatException e) {
			throw new RuntimeException("Corrupt QuickServer");
		}
		return version;
	}

	/**
	 * Returns the new line string used by QuickServer.
	 * @since 1.2
	 */
	public static String getNewLine() {
		return NEW_LINE;
	}

	/**
     * Returns the Server name : port of the QuickServer.
     */
	public String toString() {
		return serverName + " : " + getPort();
	}

	/**
	 * Creates a new server without any configuration.
	 * Make sure you configure the QuickServer, before 
	 * calling startServer()
	 * @see org.quickserver.net.server.ClientEventHandler
	 * @see org.quickserver.net.server.ClientCommandHandler
	 * @see org.quickserver.net.server.ClientObjectHandler
	 * @see org.quickserver.net.server.ClientBinaryHandler
 	 * @see org.quickserver.net.server.ClientWriteHandler
	 * @see org.quickserver.net.server.ClientAuthenticationHandler
	 * @see org.quickserver.net.server.ClientHandler
 	 * @see #configQuickServer
	 * @see #initService
	 * @see #setPort
	 * @see #setClientCommandHandler
	 * @since 1.2
	 */
	public QuickServer() {
	}

	/**
	 * Creates a new server with the specified  
	 * <code>commandHandler</code> has it {@link ClientCommandHandler}.
	 * @param commandHandler the fully qualified name of the 
	 *  desired class that implements {@link ClientCommandHandler}
	 *
	 * @see org.quickserver.net.server.ClientCommandHandler
	 * @see org.quickserver.net.server.ClientAuthenticationHandler
	 * @see org.quickserver.net.server.ClientHandler
	 * @see #setPort
	 */
	public QuickServer(String commandHandler) {
		setClientCommandHandler(commandHandler);
	}

	/**
	 * Creates a new server at <code>port</code> with the specified  
	 * <code>commandHandler</code> has it {@link ClientCommandHandler}.
	 *
	 * @param commandHandler fully qualified name of the class that
	 * implements {@link ClientCommandHandler}
	 * @param port to listen on.
	 *
	 * @see org.quickserver.net.server.ClientCommandHandler
	 * @see org.quickserver.net.server.ClientAuthenticationHandler
	 * @see org.quickserver.net.server.ClientHandler
	 */
	public QuickServer(String commandHandler,int port) {
		this(commandHandler); //send to another constructor
		setPort(port);		
	}

	/**
	 * Starts the QuickServer.
	 *
	 * @exception org.quickserver.net.AppException 
	 *  if Server already running or if it could not load the classes
	 *  [ClientCommandHandler, ClientAuthenticationHandler, ClientData].
	 * @see #startService
	 */
	public void startServer() throws AppException {
		logger.fine("Starting "+getName());

		if(isClosed() == false) {
			logger.warning("Server "+getName()+" already running.");
			throw new AppException("Server "+getName()+" already running.");
		}
		
		if(serverBanner == null) {
			serverBanner = "\n-------------------------------" + 
				           "\n Name : " + getName() +
						   "\n Port : " + getPort() + 
						   "\n-------------------------------\n";
			logger.finest("Default Server Banner Generated");
		}
		try	{
			loadApplicationClasses();

			//load class from Advanced Settings
			Class clientIdentifierClass = 
				getClass(getBasicConfig().getAdvancedSettings().getClientIdentifier(), true);
			clientIdentifier = (ClientIdentifier) 
				clientIdentifierClass.newInstance();
			clientIdentifier.setQuickServer(QuickServer.this);

			//load class from ObjectPoolConfig
			Class poolManagerClass = 
				getClass(getBasicConfig().getObjectPoolConfig().getPoolManager(), true);
			poolManager = (PoolManager) poolManagerClass.newInstance();

			//load class QSObjectPoolMaker
			Class qsObjectPoolMakerClass = getClass(
				getBasicConfig().getAdvancedSettings().getQSObjectPoolMaker(), true);
			qsObjectPoolMaker = (QSObjectPoolMaker) qsObjectPoolMakerClass.newInstance();

			loadServerHooksClasses();
			processServerHooks(ServerHook.PRE_STARTUP);
			
			if(getSecure().isLoad()==true)
				loadSSLContext(); //v1.4.0

			loadBusinessLogic();
		} catch(ClassNotFoundException e) {
			logger.severe("Could not load class/s : " + e.getMessage());
			throw new AppException("Could not load class/s : " + e.getMessage());
		} catch(InstantiationException e) {
			logger.severe("Could not instantiate class/s : " + e.getMessage());
			throw new AppException("Could not instantiate class/s : "+e.getMessage());
		} catch(IllegalAccessException e) {
			logger.severe("Illegal access to class/s : " + e.getMessage());
			throw new AppException("Illegal access to class/s : " + e.getMessage());
		} catch(IOException e) {
			logger.severe("IOException : " + e.getMessage());
			logger.fine("StackTrace:\n"+MyString.getStackTrace(e));
			throw new AppException("IOException : " + e.getMessage());
		} catch(Exception e) {
			logger.severe("Exception : " + e.getMessage());
			logger.fine("StackTrace:\n"+MyString.getStackTrace(e));
			throw new AppException("Exception : " + e);
		}

⌨️ 快捷键说明

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