📄 isoserver.java
字号:
/* * jPOS Project [http://jpos.org] * Copyright (C) 2000-2008 Alejandro P. Revilla * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */package org.jpos.iso;import java.io.PrintStream;import java.io.EOFException;import java.io.IOException;import java.io.InterruptedIOException;import java.lang.ref.WeakReference;import java.net.InetAddress;import java.net.UnknownHostException;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import java.util.Collection;import java.util.Iterator;import java.util.Observable;import java.util.Observer;import java.util.Random;import java.util.Map;import java.util.HashMap;import java.util.Vector;import org.jpos.core.Configurable;import org.jpos.core.Configuration;import org.jpos.core.ConfigurationException;import org.jpos.core.ReConfigurable;import org.jpos.util.LogEvent;import org.jpos.util.LogSource;import org.jpos.util.Loggeable;import org.jpos.util.Logger;import org.jpos.util.NameRegistrar;import org.jpos.util.ThreadPool;/** * Accept ServerChannel sessions and forwards them to ISORequestListeners * @author Alejandro P. Revilla * @author Bharavi Gade * @version $Revision: 2610 $ $Date: 2008-03-04 17:29:35 -0200 (Tue, 04 Mar 2008) $ */public class ISOServer extends Observable implements LogSource, Runnable, Observer, ISOServerMBean, ReConfigurable, Loggeable{ int port; ISOChannel clientSideChannel; ISOPackager clientPackager; Collection clientOutgoingFilters, clientIncomingFilters, listeners; ThreadPool pool; public static final int DEFAULT_MAX_THREADS = 100; public static final String LAST = ":last"; String name; protected Logger logger; protected String realm; protected String realmChannel; protected ISOServerSocketFactory socketFactory = null; public static final int CONNECT = 0; public static final int SIZEOF_CNT = 1; private int[] cnt; private String[] allow; private InetAddress bindAddr; private int backlog; protected Configuration cfg; private boolean shutdown = false; private ServerSocket serverSocket; private Map channels; private boolean ignoreISOExceptions; /** * @param port port to listen * @param clientSide client side ISOChannel (where we accept connections) * @param pool ThreadPool (created if null) */ public ISOServer(int port, ServerChannel clientSide, ThreadPool pool) { super(); this.port = port; this.clientSideChannel = clientSide; this.clientPackager = clientSide.getPackager(); if (clientSide instanceof FilteredChannel) { FilteredChannel fc = (FilteredChannel) clientSide; this.clientOutgoingFilters = fc.getOutgoingFilters(); this.clientIncomingFilters = fc.getIncomingFilters(); } this.pool = (pool == null) ? new ThreadPool (1, DEFAULT_MAX_THREADS) : pool; listeners = new Vector(); name = ""; channels = new HashMap(); cnt = new int[SIZEOF_CNT]; } protected Session createSession (ServerChannel channel) { return new Session (channel); } protected class Session implements Runnable, LogSource { ServerChannel channel; String realm; protected Session(ServerChannel channel) { this.channel = channel; realm = ISOServer.this.getRealm() + ".session"; } public void run() { if (channel instanceof BaseChannel) { LogEvent ev = new LogEvent (this, "session-start"); Socket socket = ((BaseChannel)channel).getSocket (); realm = realm + socket.getInetAddress(); try { checkPermission (socket, ev); } catch (ISOException e) { try { int delay = 1000 + new Random().nextInt (4000); ev.addMessage (e.getMessage()); ev.addMessage ("delay=" + delay); ISOUtil.sleep (delay); socket.close (); } catch (IOException ioe) { ev.addMessage (ioe); } return; } finally { Logger.log (ev); } } try { for (;;) { try { ISOMsg m = channel.receive(); Iterator iter = listeners.iterator(); while (iter.hasNext()) if (((ISORequestListener)iter.next()).process (channel, m)) break; } catch (ISOFilter.VetoException e) { Logger.log (new LogEvent (this, "VetoException", e.getMessage())); } catch (ISOException e) { if (ignoreISOExceptions) { Logger.log (new LogEvent (this, "ISOException", e.getMessage())); } else throw e; } } } catch (EOFException e) { // Logger.log (new LogEvent (this, "session-warning", "<eof/>")); } catch (SocketException e) { // if (!shutdown) // Logger.log (new LogEvent (this, "session-warning", e)); } catch (InterruptedIOException e) { // nothing to log } catch (Throwable e) { Logger.log (new LogEvent (this, "session-error", e)); } try { channel.disconnect(); } catch (IOException ex) { Logger.log (new LogEvent (this, "session-error", ex)); } Logger.log (new LogEvent (this, "session-end")); } public void setLogger (Logger logger, String realm) { } public String getRealm () { return realm; } public Logger getLogger() { return ISOServer.this.getLogger(); } public void checkPermission (Socket socket, LogEvent evt) throws ISOException { if (allow != null && allow.length > 0) { String ip = socket.getInetAddress().getHostAddress (); for (int i=0; i<allow.length; i++) { if (ip.equals (allow[i])) { evt.addMessage ("access granted, ip=" + ip); return; } } throw new ISOException ("access denied, ip=" + ip); } } } /** * add an ISORequestListener * @param l request listener to be added * @see ISORequestListener */ public void addISORequestListener(ISORequestListener l) { listeners.add (l); } /** * remove an ISORequestListener * @param l a request listener to be removed * @see ISORequestListener */ public void removeISORequestListener(ISORequestListener l) { listeners.remove (l); } /** * Shutdown this server */ public void shutdown () { shutdown = true; new Thread ("ISOServer-shutdown") { public void run () { shutdownServer (); if (!cfg.getBoolean ("keep-channels")) shutdownChannels (); } }.start(); } private void shutdownServer () { try { if (serverSocket != null) serverSocket.close (); if (pool != null) pool.close(); } catch (IOException e) { Logger.log (new LogEvent (this, "shutdown", e)); } } private void shutdownChannels () { Iterator iter = channels.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); WeakReference ref = (WeakReference) entry.getValue(); ISOChannel c = (ISOChannel) ref.get (); if (c != null) { try { c.disconnect (); } catch (IOException e) { Logger.log (new LogEvent (this, "shutdown", e)); } } } } private void purgeChannels () { Iterator iter = channels.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); WeakReference ref = (WeakReference) entry.getValue(); ISOChannel c = (ISOChannel) ref.get (); if (c == null || (!c.isConnected())) iter.remove (); } } public void run() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -