📄 basicclienthandler.java
字号:
}
/**
* Checks if the client is still connected.
* @exception SocketException if Socket is not open.
* @since 1.4.5
*/
public boolean isConnected() throws SocketException {
if(isOpen()==false)
throw new SocketException("Connection is no more open!");
else
return true;
}
/**
* Checks if the client is still connected and if socket is open. This is same as isConnected()
* but does not throw SocketException.
* @since 1.4.6
*/
public boolean isOpen() {
if(lost==true || socket==null || socket.isConnected()==false || socket.isClosed()==true)
return false;
else
return true;
}
/**
* Checks if the client is closed.
* @since 1.4.1
*/
public boolean isClosed() {
if(socket==null || socket.isClosed()==true)
return true;
else
return false;
}
/**
* Send a String message to the connected client
* it adds a new line{\r\n} to the end of the string.
* If client is not connected it will just return.
* @exception IOException
* if Socket IO Error or Socket was closed by the client.
*/
public void sendClientMsg(String msg) throws IOException {
isConnected();
if(dataModeOUT != DataMode.STRING)
throw new IllegalStateException("Can't send String :" +
"DataType.OUT is not in DataMode.STRING");
if(getCommunicationLogging()) {
appLogger.fine("Sending ["+getHostAddress()+"] : "+msg);
}
byte data[] = msg.getBytes(charset);
b_out.write(data, 0, data.length);
b_out.write(NEW_LINE_BYTES, 0, NEW_LINE_BYTES.length);
b_out.flush();
updateLastCommunicationTime();
}
/**
* Send a String message to the connected client as a string of bytes.
* If client is not connected it will just return.
* @since 1.3.1
* @exception IOException
* if Socket IO Error or Socket was closed by the client.
*/
public void sendClientBytes(String msg) throws IOException {
isConnected();
if (dataModeOUT != DataMode.BYTE)
throw new IllegalStateException("Can't send String :" +
"DataType.OUT is not in DataMode.BYTE");
if(getCommunicationLogging()) {
appLogger.fine("Sending ["+getHostAddress()+"] : "+msg);
}
byte data[] = msg.getBytes(charset);
b_out.write(data,0,data.length);
b_out.flush();
updateLastCommunicationTime();
}
/**
* Send a Object message to the connected client. The message Object
* passed must be serializable. If client is not connected it
* will just return.
* @exception IOException if Socket IO Error or Socket was closed
* by the client.
* @exception IllegalStateException if DataType.OUT is not in
* DataMode.OBJECT
* @see #setDataMode
* @since 1.2
*/
public void sendClientObject(Object msg) throws IOException {
isConnected();
if(dataModeOUT != DataMode.OBJECT)
throw new IllegalStateException("Can't send Object : DataType.OUT is not in DataMode.OBJECT");
if(getCommunicationLogging()) {
appLogger.fine("Sending ["+getHostAddress()+"] : "+msg.toString());
}
o_out.writeObject(msg);
o_out.flush();
updateLastCommunicationTime();
}
/**
* Send a String message to the logger associated with
* {@link QuickServer#getAppLogger} with Level.INFO as its level.
*/
public void sendSystemMsg(String msg) {
sendSystemMsg(msg, Level.INFO);
}
/**
* Send a String message to the logger associated with
* {@link QuickServer#getAppLogger}.
* @since 1.2
*/
public void sendSystemMsg(String msg, Level level) {
appLogger.log(level, msg);
}
/**
* Send a String message to the system output stream.
* @param newline indicates if new line required at the end.
* @deprecated Use {@link #sendSystemMsg(java.lang.String)},
* since it uses Logging.
*/
public void sendSystemMsg(String msg, boolean newline) {
if(newline)
System.out.println(msg);
else
System.out.print(msg);
}
public abstract void run();
protected void prepareForRun() throws SocketException, IOException {
clientConnectedTime = new java.util.Date(); //v1.3.2
lastCommunicationTime = clientConnectedTime;//v1.3.3
setCharset(getServer().getBasicConfig().getAdvancedSettings().getCharset());//1.4.5
hostAddress = getSocket().getInetAddress().getHostAddress();//1.4.5
port = getSocket().getPort();
if(logger.isLoggable(Level.FINEST)) {
StringBuffer sb = new StringBuffer();
sb.append(getName());
sb.append(" -> ");
sb.append(hostAddress);
sb.append(':');
sb.append(port);
logger.finest(sb.toString());
}
socket.setSoTimeout(socketTimeout);
connection = true;
dataModeIN = getServer().getDefaultDataMode(DataType.IN);
dataModeOUT = getServer().getDefaultDataMode(DataType.OUT);
updateInputOutputStreams();
}
protected void processMaxConnection(ClientEvent currentEvent) throws IOException {
if(clientExtendedEventHandler!=null) {
if(clientExtendedEventHandler.handleMaxConnection(this)) {
removeEvent(getThreadEvent());
if(getThreadEvent()==ClientEvent.MAX_CON) {
currentEvent = ClientEvent.ACCEPT;
} else if(getThreadEvent()==ClientEvent.MAX_CON_BLOCKING) {
currentEvent = ClientEvent.RUN_BLOCKING;
} else {
throw new IllegalArgumentException("Unknown ClientEvent: "+getThreadEvent());
}
synchronized(clientEvents) {
clientEvents.add(currentEvent);
}
threadEvent.set(currentEvent);
}
} else if(maxConnectionMsg.length()!=0) {
out.write(maxConnectionMsg.getBytes(charset), 0, maxConnectionMsg.length());
out.write(NEW_LINE_BYTES, 0, NEW_LINE_BYTES.length);
out.flush();
}
}
protected AuthStatus processAuthorisation() throws SocketException,
IOException, AppException {
logger.finest("INSIDE");
while(authorised==false && connection==true) {
isConnected();
counAuthTry++;
if(authorised == false) {
if(counAuthTry > maxAuthTry) {
processMaxAuthTry();
}
}
try {
if(clientAuthenticationHandler!=null) {
return clientAuthenticationHandler.askAuthentication(this);
} else if(authenticator!=null) {
authorised = authenticator.askAuthorisation(this);
}
} catch(NullPointerException e) {
logger.severe("Authenticator implementation has not handled null properly."+
" Input from client should be checked for null!");
throw e;
} catch(SocketTimeoutException e) {
handleTimeout(e);
}
updateLastCommunicationTime();
} //end of auth while
return AuthStatus.SUCCESS;
}
private void processMaxAuthTry() throws SocketException, IOException, AppException {
if(clientExtendedEventHandler!=null) {
clientExtendedEventHandler.handleMaxAuthTry(this);
} else {
String temp = maxAuthTryMsg;
if(dataModeOUT == DataMode.STRING)
temp = temp + NEW_LINE;
if(dataModeOUT != DataMode.OBJECT) {
out.write(temp.getBytes(charset));
out.flush();
}
}
appLogger.warning("Max Auth Try Reached - Client : "+getHostAddress());
if(true) throw new AppException(maxAuthTryMsg);
}
protected void notifyCloseOrLost() throws IOException {
synchronized(this) {
if(closeOrLostNotified==false) {
if(lost==true) {
clientEventHandler.lostConnection(this);
} else {
clientEventHandler.closingConnection(this);
}
closeOrLostNotified = true;
}
}
}
protected synchronized void returnClientData() {
if(clientData==null || getServer().getClientDataPool()==null)
return;
logger.finest("Returning ClientData to pool");
try {
getServer().getClientDataPool().returnObject(clientData);
clientData = null;
} catch(Exception e) {
logger.warning("IGNORED: Could not return ClientData to pool: "+e);
}
}
protected void returnClientHandler() {
try {
synchronized(lockObj) {
logger.finest(Thread.currentThread().getName()+" returning "+getName());
getServer().getClientHandlerPool().returnObject(this);
}
} catch(Exception e) {
logger.warning("IGNORED: Could not return ClientHandler to pool: "+e);
}
}
/**
* Returns the ClientHandler name
* @since 1.4.6
*/
public String getName() {
return name;
}
/**
* Returns the ClientHandler detailed information.
* If ClientData is present and is ClientIdentifiable will return ClientInfo else
* it will return Clients InetAddress and port information.
*/
public String info() {
StringBuffer sb = new StringBuffer();
sb.append("{");
sb.append(name);
sb.append(" - ");
String info = getClientIdentifiable(this);
if(info!=null) {
sb.append("[ClientInfo: ");
sb.append(info);
sb.append(']');
}
if(getSocket()==null || getSocket().isClosed()==true) {
sb.append("[non-connected]");
} else if(info==null) {
sb.append('[');
sb.append(hostAddress);
sb.append(':');
sb.append(port);
sb.append(']');
}
sb.append('}');
return sb.toString();
}
/**
* Returns the ClientHandler information.
* If ClientData is present and is ClientIdentifiable will return ClientInfo else
* it will return Clients InetAddress and port information.
*/
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("{");
sb.append(name);
sb.append(" - ");
if(getSocket()==null || getSocket().isClosed()==true) {
sb.append("[non-connected]");
} else if(hostAddress!=null) {
sb.append('[');
sb.append(hostAddress);
sb.append(':');
sb.append(port);
sb.append(']');
}
synchronized(clientEvents) {
if(clientEvents.size()!=0) {
sb.append(' ');
sb.append(clientEvents);
}
}
sb.append('}');
return sb.toString();
}
protected static String getClientIdentifiable(ClientHandler foundClientHandler) {
if(foundClientHandler==null) return null;
ClientData foundClientData = null;
foundClientData = foundClientHandler.getClientData();
if(foundClientData==null)
return null;
else if(ClientIdentifiable.class.isInstance(foundClientData)==false)
return null;
else
return ((ClientIdentifiable)foundClientData).getClientInfo();
}
/**
* Sets the {@link DataMode} for the ClientHandler
*
* Note: When mode is DataMode.OBJECT and type is DataType.IN
* this call will block until the client ObjectOutputStream has
* written and flushes the header.
* @since 1.2
* @exception IOException if mode could not be changed.
* @param dataMode mode of data exchange - String or Object.
* @param dataType type of data for which mode has to be set.
*/
public abstract void setDataMode(DataMode dataMode, DataType dataType) throws IOException;
protected void checkDataModeSet(DataMode dataMode, DataType dataType) {
if(dataMode==DataMode.STRING && dataType==DataType.IN && clientCommandHandler==null) {
throw new IllegalArgumentException("Can't set DataType.IN mode to STRING when ClientCommandHandler is not set!");
}
if(dataMode==DataMode.BYTE && dataType==DataType.IN && clientCommandHandler==null) {
throw new IllegalArgumentException("Can't set DataType.IN mode to BYTE when ClientCommandHandler is not set!");
}
if(dataMode==DataMode.OBJECT && dataType==DataType.IN && clientObjectHandler==null) {
throw new IllegalArgumentException("Can't set DataType.IN mode to OBJECT when ClientObjectHandler is not set!");
}
if(dataMode==DataMode.BINARY && dataType==DataType.IN && clientBinaryHandler==null) {
throw new IllegalArgumentException("Can't set DataType.IN mode to BINARY when ClientBinaryHandler is not set!");
}
}
/**
* Returns the {@link DataMode} of the ClientHandler for the
* DataType.
* @since 1.2
*/
public DataMode getDataMode(DataType dataType) {
if(dataType == DataType.IN)
return dataModeIN;
else if(dataType == DataType.OUT)
return dataModeOUT;
else
throw new IllegalArgumentException("Unknown DataType : " +
dataType);
}
/**
* Returns the {@link java.sql.Connection} object for the
* DatabaseConnection that is identified by id passed. If id passed
* does not match with any connection loaded by this class it will
* return <code>null</code>.
* This just calls <code>getServer().getDBPoolUtil().getConnection(id)</code>
* @since 1.3
* @deprecated as of v1.4.5 use <code>getServer().getDBPoolUtil().getConnection(id)</code>
*/
public java.sql.Connection getConnection(String id) throws Exception {
if(getServer()==null)
throw new Exception("ClientHandler no longer is associated with any client! Try to use quickserver.getDBPoolUtil().getConnection("+id+")");
return getServer().getDBPoolUtil().getConnection(id);
}
/**
* Returns the date/time when the client socket was assigned to this
* ClientHanlder. If no client is currently connected it will return
* <code>null</code>
* @since 1.3.1
*/
public Date getClientConnectedTime() {
return clientConnectedTime;
}
/**
* Read the byte input. This will block till some data is
* received from the stream.
* @return The data as a String
* @since 1.3.1
*/
protected abstract byte[] readInputStream() throws IOException;
protected static byte[] readInputStream(InputStream _in) throws IOException {
byte data[] = null;
if(_in==null)
throw new IOException("InputStream can't be null!");
int s = _in.read();
if(s==-1) {
return null; //Connection lost
}
int alength = _in.available();
if(alength > 0) {
data = new byte[alength+1];
_in.read(data, 1, alength);
} else {
data = new byte[1];
}
data[0] = (byte)s;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -