📄 basicclienthandler.java
字号:
/*
* 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 + -