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

📄 basicclienthandler.java

📁 一个用java编写的服务器,对于学习网络编程的人来说是个很好的例子
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * This file is part of the QuickServer library 
 * Copyright (C) 2003-2005 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.impl;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.InetAddress;
import java.util.*;
import java.util.logging.*;
import javax.net.ssl.*;
import java.security.*;
import java.nio.*;
import java.nio.channels.*;

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

/**
 * Basic implementation of ClientHandler that handles clients for QuickServer.
 * <p> This class is used by {@link QuickServer} to handle each new client 
 * connected. This class is responsible to handle client sockets. It can operate 
 * in both blocking mode and non-blocking mode (java nio).</p>
 * <p>
 * Contributions By: 
 *   Martin Benns : BYTE Mode
 * </p>
 * @author Akshathkumar Shetty
 * @author Martin Benns : Added BYTE mode
 */
public abstract class BasicClientHandler implements ClientHandler {
	private static final Logger logger = Logger.getLogger(BasicClientHandler.class.getName());

	protected static final String NEW_LINE = QuickServer.getNewLine();
	protected static final byte NEW_LINE_BYTES[] = NEW_LINE.getBytes();

	//Some variable are not initialised to any value because the 
	//default java value was desired initial value. 
	
	/** Client socket */
	protected Socket socket;
	/** Client authorisation status */
	protected volatile boolean authorised;
	/** Count of client login attempts */
	protected int counAuthTry;
	/** max allowed login attempts */
	protected int maxAuthTry = 5;
	/** timeout message */
	protected String timeoutMsg;
	/** Message to be displayed when max login attempt reaches.*/
	protected String maxAuthTryMsg;	

	protected int socketTimeout;
	protected volatile boolean connection; //false
	protected boolean lost; //false
	
	protected QuickServer quickServer;
	protected Authenticator authenticator; //v1.3
	protected ClientAuthenticationHandler clientAuthenticationHandler; //v1.4.6
	protected ClientEventHandler clientEventHandler; //v1.4.6
	protected ClientExtendedEventHandler clientExtendedEventHandler; //v1.4.6
	protected ClientCommandHandler clientCommandHandler;
	protected ClientObjectHandler clientObjectHandler; //v1.2
	protected ClientBinaryHandler clientBinaryHandler; //1.4
	protected ClientData clientData;

	protected InputStream in;
	protected OutputStream out;
	protected BufferedReader bufferedReader;
	//if DataMode.OBJECT
	protected ObjectOutputStream o_out; //v1.2
	protected ObjectInputStream o_in; //v1.2
	//added for BYTE mode and BINARY mode
	protected BufferedInputStream b_in;
	protected BufferedOutputStream b_out;

	//logger for the application using this QuickServer
	protected Logger appLogger; 
	protected DataMode dataModeIN = null;
	protected DataMode dataModeOUT = null;

	protected boolean communicationLogging = true;
	protected Date clientConnectedTime = null;	
	protected Date lastCommunicationTime = null;
	protected boolean secure = false;	

	//--v1.4.5
	protected static final ThreadLocal threadEvent = new ThreadLocal();

	protected String maxConnectionMsg;
	protected Set clientEvents = new HashSet();	
	protected List unprocessedClientEvents = Collections.synchronizedList(new ArrayList());
	
	protected volatile boolean closeOrLostNotified;
	protected Object lockObj = new Object();
	protected volatile boolean willClean;
	protected String charset;

	private static Map idMap = new HashMap();
	private int instanceCount;
	private int id;
	private String name;
	private String hostAddress;
	private int port;

	static class InstanceId {
		private int id = 0;
		public int getNextId() {
			return ++id;
		}
	};

	private static int getNewId(int instanceCount) {
		InstanceId instanceId = (InstanceId) idMap.get(""+instanceCount);
		if(instanceId==null) {
			instanceId = new InstanceId();
			idMap.put(""+instanceCount, instanceId);
		}
		return instanceId.getNextId();
	}

	public BasicClientHandler(int instanceCount) {
		this.instanceCount = instanceCount;
		id = getNewId(instanceCount);

		StringBuffer sb = new StringBuffer();
		sb.append("<ClientHandler-Pool#");
		sb.append(instanceCount);
		sb.append("-ID:");
		sb.append(id);
		sb.append(">");
		name = sb.toString();
	}

	public int getInstanceCount() {
		return instanceCount;
	}


	public BasicClientHandler() {
		this(-1);
	}	
	
	public void clean() {
		counAuthTry = 0;
		authorised = false;
		in = null;
		out = null;
		bufferedReader = null;
		o_out = null; o_in = null;
		b_in = null; b_out = null;

		dataModeIN = null;
		dataModeOUT = null;

		lost = false;
		clientData = null;
		clientConnectedTime = null;
		lastCommunicationTime = null;
		communicationLogging = true;
		socketTimeout = 0;
		secure = false;
		
		authenticator = null;
		clientAuthenticationHandler = null;//1.4.6
		clientCommandHandler = null;
		clientObjectHandler = null;
		clientBinaryHandler = null;//1.4		
		clientData = null;

		maxConnectionMsg = null;
		synchronized(clientEvents) {
			clientEvents.clear();
			unprocessedClientEvents.clear();
		}		

		closeOrLostNotified = false;

		if(socket!=null) {
			try {
				socket.close();
			} catch(Exception er) {
				appLogger.warning("Error in closing socket: "+er);
			}
			socket = null;
		}

		hostAddress = null;
		port = 0;

		quickServer = null;
		willClean  = false;
		charset = null;
	}

	protected void finalize() throws Throwable {
		super.finalize(); 
	}

	/**
	 * Associates the ClientHanlder with the client encapsulated by 
	 * <code>theClient</code>.
	 * @param theClient object that encapsulates client socket 
	 *  and its configuration details.
	 */
	public void handleClient(TheClient theClient) {
		setServer(theClient.getServer());

		if(getServer().isRunningSecure()==true) {
			setSecure(true);
		}
		setSocket(theClient.getSocket());

		if(theClient.getTrusted()==false) {
			setAuthenticator(theClient.getAuthenticator());
			setClientAuthenticationHandler(theClient.getClientAuthenticationHandler());
		}
		setClientEventHandler(theClient.getClientEventHandler());
		setClientExtendedEventHandler(theClient.getClientExtendedEventHandler());
		setClientCommandHandler(theClient.getClientCommandHandler());
		setClientObjectHandler(theClient.getClientObjectHandler());
		setClientBinaryHandler(theClient.getClientBinaryHandler()); //v1.4
		
		setClientData(theClient.getClientData());
		if(theClient.getTrusted()==false) {
			socketTimeout = theClient.getTimeout();
		}
		timeoutMsg = theClient.getTimeoutMsg();
		maxAuthTryMsg = theClient.getMaxAuthTryMsg();
		maxAuthTry = theClient.getMaxAuthTry(); //v1.2
		appLogger = quickServer.getAppLogger(); //v1.2
		
		setCommunicationLogging(theClient.getCommunicationLogging()); //v1.3.2

		maxConnectionMsg = theClient.getMaxConnectionMsg();//1.4.5
		addEvent(theClient.getClientEvent());//1.4.5
	}

	/**
     * Returns the QuickServer object that created it.
     * @see #setServer
     */
	public QuickServer getServer() {
		return quickServer;
	}
	/**
     * Sets the QuickServer object associated with this ClientHandler.
     * @see #getServer
     */
	protected void setServer(QuickServer server) {
		Assertion.affirm(server!=null, "QuickServer can't be null!");
		quickServer = server;
	}
	
	/**
     * Sets the ClientData object associated with this ClientHandler
	 * @see ClientData
     * @see #getClientData
     */
	protected void setClientData(ClientData data) {
		this.clientData = data;
	}
	/**
     * Returns the ClientData object associated with this ClientHandler, 
	 * if not set will return <code>null</code>
	 * @see ClientData
     * @see #setClientData
     */
	public ClientData getClientData() {
		return clientData;
	}

	/**
     * Sets the ClientAuthenticationHandler class that handles the 
	 * authentication of a client.
	 * @param clientAuthenticationHandler fully qualified name of the class that 
	 * implements {@link ClientAuthenticationHandler}.
	 * @since 1.4.6
     */
	protected void setClientAuthenticationHandler(ClientAuthenticationHandler clientAuthenticationHandler) {
		this.clientAuthenticationHandler = clientAuthenticationHandler;
	}

	/**
     * Sets the Authenticator class that handles the 
	 * authentication of a client.
	 * @param authenticator fully qualified name of the class that 
	 * implements {@link Authenticator}.
	 * @since 1.3
     */
	protected void setAuthenticator(Authenticator authenticator) {
		this.authenticator = authenticator;
	}

	/**
	 * Returns the {@link java.io.InputStream} associated with 
	 * the Client being handled.
	 * @see #setInputStream
	 */
	public InputStream getInputStream() {
		return in;
	}
	/**
	 * Sets the {@link java.io.InputStream} associated with 
	 * the Client being handled.
	 * @since 1.1
	 * @see #getInputStream
	 */
	protected abstract void setInputStream(InputStream in) throws IOException;

	/**
	 * Returns the {@link java.io.OutputStream} associated with 
	 * the Client being handled.
	 * @see #setOutputStream
	 */
	public OutputStream getOutputStream() {
		return out;
	}
	/**
	 * Set the {@link java.io.OutputStream} associated with 
	 * the Client being handled.
	 * @since 1.1
	 * @see #getOutputStream
	 * @exception IOException if ObjectOutputStream could not be created.
	 */
	public void setOutputStream(OutputStream out) throws IOException {
		this.out = out;
		if(getDataMode(DataType.OUT) == DataMode.STRING || 
				getDataMode(DataType.OUT) == DataMode.BYTE || 
				getDataMode(DataType.OUT) == DataMode.BINARY) {
			o_out = null;
			b_out = new BufferedOutputStream(out);
		} else if(getDataMode(DataType.OUT) == DataMode.OBJECT) {
			b_out = null;
			o_out = new ObjectOutputStream(out);
			o_out.flush();
		} else {
			throw new IllegalStateException("Unknown DataMode " +getDataMode(DataType.OUT));
		}
	}
	
	/**
	 * Returns the {@link java.io.BufferedReader} associated with 
	 * the Client being handled. Note that this is only available under blocking mode. 
	 * @see #getBufferedWriter
	 */
	public abstract BufferedReader getBufferedReader();

	/**
	 * Returns the {@link java.io.BufferedWriter} associated with 
	 * the Client being handled.
	 * @deprecated since 1.4.5 use getOutputStream()
	 */
	public BufferedWriter getBufferedWriter() {
		return new BufferedWriter(new OutputStreamWriter(b_out));
	}

	/**
	 * Returns the {@link java.io.ObjectOutputStream} associated with 
	 * the Client being handled.
	 * It will be <code>null</code> if no {@link ClientObjectHandler} 
	 * was set in {@link QuickServer}.
	 * @see #getObjectInputStream
	 * @since 1.2
	 */
	public ObjectOutputStream getObjectOutputStream() {
		return o_out;
	}
	/**
	 * Returns the {@link java.io.ObjectInputStream} associated with 
	 * the Client being handled.
	 * It will be <code>null</code> if no {@link ClientObjectHandler} 
	 * was set in {@link QuickServer}.
	 * @see #getObjectOutputStream
	 * @since 1.2
	 */
	public ObjectInputStream getObjectInputStream() {
		return o_in;
	}

	/**
     * Sets the ClientEventHandler class that gets notified of client events.
	 * @since 1.4.6
     */
	protected void setClientEventHandler(ClientEventHandler handler) {
		clientEventHandler=handler;
	}

	/**
     * Sets the ClientExtendedEventHandler class that gets notified of extended client events.
	 * @since 1.4.6
     */
	protected void setClientExtendedEventHandler(ClientExtendedEventHandler handler) {
		clientExtendedEventHandler=handler;
	}

	/**
     * Sets the ClientCommandHandler class that interacts with 
	 * client sockets.
     */
	protected void setClientCommandHandler(ClientCommandHandler handler) {
		clientCommandHandler=handler;
	}

	/**
     * Sets the ClientObjectHandler class that interacts with 
	 * client sockets.
	 * @param handler fully qualified name of the class that 
	 * implements {@link ClientObjectHandler}
	 * @since 1.2
     */
	protected void setClientObjectHandler(ClientObjectHandler handler) {
		clientObjectHandler = handler;
	}

	/** Closes client socket associated. */
	public abstract void closeConnection();

	/** Returns client socket associated. */
	public Socket getSocket() {
		return socket;
	}

	/** 
	 * Returns client socket associated. 
	 * @since 1.4.0
	 * @see #updateInputOutputStreams
	 */
	public void setSocket(Socket socket) {
		this.socket = socket;
	}

	/**
	 * Checks if the client is still connected.
	 * @exception SocketException if Socket is not open.
	 * @deprecated since 1.4.5 Use {@link #isConnected}
	 */
	public boolean isConected() throws SocketException {
		return isConnected();

⌨️ 快捷键说明

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