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

📄 basicclienthandler.java

📁 一个用java编写的服务器,对于学习网络编程的人来说是个很好的例子
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	}

	/**
	 * 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 + -