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

📄 connection.java

📁 SMPP(点到点短消息协议)的java实现
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package ie.omk.smpp;import ie.omk.smpp.event.ConnectionObserver;import ie.omk.smpp.event.EventDispatcher;import ie.omk.smpp.event.ReceiverExceptionEvent;import ie.omk.smpp.event.ReceiverExitEvent;import ie.omk.smpp.event.ReceiverStartEvent;import ie.omk.smpp.event.SMPPEvent;import ie.omk.smpp.event.SimpleEventDispatcher;import ie.omk.smpp.message.Bind;import ie.omk.smpp.message.BindResp;import ie.omk.smpp.message.DeliverSM;import ie.omk.smpp.message.DeliverSMResp;import ie.omk.smpp.message.EnquireLink;import ie.omk.smpp.message.EnquireLinkResp;import ie.omk.smpp.message.InvalidParameterValueException;import ie.omk.smpp.message.SMPPPacket;import ie.omk.smpp.message.SMPPProtocolException;import ie.omk.smpp.message.SMPPRequest;import ie.omk.smpp.message.SMPPResponse;import ie.omk.smpp.message.Unbind;import ie.omk.smpp.message.UnbindResp;import ie.omk.smpp.message.tlv.Tag;import ie.omk.smpp.net.SmscLink;import ie.omk.smpp.net.TcpLink;import ie.omk.smpp.util.APIConfig;import ie.omk.smpp.util.AlphabetEncoding;import ie.omk.smpp.util.DefaultSequenceScheme;import ie.omk.smpp.util.PacketFactory;import ie.omk.smpp.util.PropertyNotFoundException;import ie.omk.smpp.util.SMPPIO;import ie.omk.smpp.util.SequenceNumberScheme;import ie.omk.smpp.version.SMPPVersion;import ie.omk.smpp.version.VersionException;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.net.SocketTimeoutException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * SMPP client connection (ESME). An SMPP Connection represents any kind of * connection to the SMSC, be it a transmitter, receiver or transceiver. It also * supports both synchronous and asynchronous modes of communication. * Synchronous mode is only useful for very simple applications that use * single-threading. Asynchronous mode is recommended for more complex * applications, especially those that will be running many threads. * <p> * <b>Important Note </b>: if you wish to use synchronous mode in a * multi-threaded environment, it is the <u>application's </u> responsiblity to * ensure there is only one thread executing a call to either or both of the * <code>sendRequest</code> and <code>readNextPacket</code> methods. If * there are concurrent calls to these methods executing, there is a strong * possibility of the incorrect packet being returned in a particular thread and * both the API and the application getting confused. These are the only methods * that contain such a race condition. * </p> *  * @author Oran Kelly * @version $Id: Connection.java 302 2006-08-10 20:36:40Z orank $ */public class Connection implements java.lang.Runnable {    /** SMPP Transmitter connection type. */    public static final int TRANSMITTER = 1;    /** SMPP Receiver connection type. */    public static final int RECEIVER = 2;    /** SMPP Transciever connection type. */    public static final int TRANSCEIVER = 3;    /** Connection state: not bound to the SMSC. */    public static final int UNBOUND = 0;    /**     * Connection state: waiting for successful acknowledgement to bind request.     */    public static final int BINDING = 1;    /** Connection state: bound to the SMSC. */    public static final int BOUND = 2;    /**     * Connection state: waiting for successful acknowledgement to unbind     * request or waiting for application to respond to unbind request.     */    public static final int UNBINDING = 3;    private static final Log LOGGER = LogFactory.getLog(Connection.class);    /** Type of this SMPP connection. */    private int connectionType;    /** Packet listener thread for Asyncronous comms. */    private Thread rcvThread;    /**     * Queue of incoming packets to deliver to application before reading from     * the network. The queue is used only in syncrhonized mode. In the case     * where an application has sent a request to the SMSC and is blocked     * waiting a response and the SMSC initiates a request of it's own (an     * unbind request or an enquire_link), the API will cache the request packet     * and wait for the response to it's packet. Any other type of packet will     * be added to the packetQueue and subsequent calls to     * <code>readNextPacket</code> will clear this queue.     */    private List packetQueue;    /**     * Object used to notify observers of SMPP events.     */    private EventDispatcher eventDispatcher;    /** Byte buffer used in readNextPacketInternal. */    private byte[] buf = new byte[300];    /** Sequence numbering scheme to use for this connection. */    private SequenceNumberScheme seqNumScheme = new DefaultSequenceScheme();    /** The network link (virtual circuit) to the SMSC */    private SmscLink link;    /**     * SMPP protocol version number.     */    protected SMPPVersion interfaceVersion = SMPPVersion.getDefaultVersion();    /**     * Does the remote end support optional parameters? According to the     * SMPPv3.4 specification, if the SMSC does not return the     * sc_interface_version optional parameter in its bind response packet, then     * we must assume it does not support optional parameters.     */    protected boolean supportOptionalParams = true;    /**     * Current state of the SMPP connection. Possible states are UNBOUND,     * BINDING, BOUND and UNBINDING.     */    private transient int state = UNBOUND;    /**     * Specify whether the listener thread will automatically ack enquire_link     * primitives received from the Smsc     */    protected boolean ackQryLinks = true;    /**     * Automatically acknowledge incoming deliver_sm messages. Only valid for     * the Receiver     */    protected boolean ackDeliverSm;    /** Is the user using synchronous are async communication?. */    protected boolean asyncComms;    /**     * The default alphabet to use for this connection.     */    protected AlphabetEncoding defaultAlphabet;    /**     * Initialise a new SMPP connection object. This is a convenience     * constructor that will create a new {@link ie.omk.smpp.net.TcpLink}object     * using the host name and port provided. The connection created will use     * synchronous communications.     *      * @param host     *            the hostname of the SMSC.     * @param port     *            the port to connect to. If 0, use the default SMPP port     *            number.     */    public Connection(String host, int port)            throws java.net.UnknownHostException {        this(new TcpLink(host, port), false);    }    /**     * Initialise a new SMPP connection object. This is a convenience     * constructor that will create a new {@link ie.omk.smpp.net.TcpLink}object     * using the host name and port provided.     *      * @param host     *            the hostname of the SMSC.     * @param port     *            the port to connect to. If 0, use the default SMPP port     *            number.     * @param async     *            true for asyncronous communication, false for synchronous.     */    public Connection(String host, int port, boolean async)            throws java.net.UnknownHostException {        this(new TcpLink(host, port), async);    }    /**     * Initialise a new SMPP connection object. The connection will use     * synchronous communications.     *      * @param link     *            The network link object to the Smsc (cannot be null)     */    public Connection(SmscLink link) {        this(link, false);    }    /**     * Initialise a new SMPP connection object, specifying the type of     * communication desired. See the {@link Connection}class description for     * some required knowledge on using the Connection in syncrhonous mode.     *      * @param link     *            The network link object to the Smsc (cannot be null)     * @param async     *            true for asyncronous communication, false for synchronous.     */    public Connection(SmscLink link, boolean async) {        this.link = link;        this.asyncComms = async;        if (asyncComms) {            initAsyncComms();        } else {            initSyncComms();        }    }    private void initAsyncComms() {        String className = "";        try {            className = APIConfig.getInstance().getProperty(                    APIConfig.EVENT_DISPATCHER_CLASS);            if (className != null && !"".equals(className)) {                Class cl = Class.forName(className);                Constructor ctr = cl.getConstructor(new Class[0]);                eventDispatcher =                    (EventDispatcher) ctr.newInstance(new Object[0]);            } else {                LOGGER.info("EventDispatcher property value is empty.");            }        } catch (PropertyNotFoundException x) {            LOGGER.debug("No event dispatcher specified in properties. Using default.");        } catch (ClassNotFoundException x) {            LOGGER.error("Cannot locate event dispatcher class " + className, x);        } catch (ClassCastException x) {            LOGGER.error(className + " does not implement the EventDispatcher interface.", x);        } catch (NoSuchMethodException x) {            LOGGER.error(className + " does not have a no-argument constructor.");        } catch (IllegalAccessException x) {            LOGGER.error(className + " constructor is not visible.", x);        } catch (IllegalArgumentException x) {            LOGGER.error("Internal error in the SMPPAPI. Please inform the maintainer.", x);        } catch (InstantiationException x) {            LOGGER.error("Could not instantiate an instance of " + className, x);        } catch (InvocationTargetException x) {            LOGGER.error(className + " constructor threw an exception.", x);        } finally {            if (eventDispatcher == null) {                eventDispatcher = new SimpleEventDispatcher();            }        }        LOGGER.info("Using event dispatcher "                + eventDispatcher.getClass().getName());        // Initialise the event dispatcher        eventDispatcher.init();        // Create the receiver daemon thread.        createRecvThread();    }    private void initSyncComms() {        packetQueue = new ArrayList();    }    /**     * Create the receiver thread if asynchronous communications is on, does     * nothing otherwise.     */    private void createRecvThread() {        LOGGER.info("Creating receiver thread");        rcvThread = new Thread(this, "ReceiverDaemon");        rcvThread.setDaemon(true);    }    /**     * Set the default alphabet of the SMSC this <code>Connection</code> is     * communicating with. Each SMSC has its own default alphabet it uses. When     * messages arrive and announce themselves with a data coding value of zero,     * that means the message is encoded in the SMSC's default alphabet. The     * smppapi assumes the GSM default alphabet as it's default alphabet. By     * setting the default alphabet on the <code>Connection</code> all packets     * returned by {@link #newInstance(int)}will use the Connection's default     * alphabet plus any packets read from the wire with a data coding value of     * zero will have their default alphabet initialised appropriately.     *      * @param alphabet     *            the alphabet to use as the default for this connection (may be     *            <code>null</code> in which case the API falls back to using     *            its own internal default).     */    public void setDefaultAlphabet(AlphabetEncoding alphabet) {        this.defaultAlphabet = alphabet;    }    /**     * Get the current alphabet this <code>Connection</code> is using as its     * default.     *      * @return the default alphabet for this <code>Connection</code>.     */    public AlphabetEncoding getDefaultAlphabet() {        return defaultAlphabet;    }    /**     * Set the state of this ESME.     *      * @see ie.omk.smpp.Connection#getState     */    private void setState(int state) {        LOGGER.info("Setting state " + state);        this.state = state;    }    /**     * Set the SMPP version this connection will use. Setting the version is     * only a valid operation before the connection is bound. Any attempt to set     * the version after binding to the SMSC will result in an exception being     * thrown.     *      * @param version     *            the SMPP version to use.     * @throws ie.omk.smpp.version.VersionException     *             if an attempt is made to set the version of the connection     *             after binding to the SMSC.     * @see ie.omk.smpp.version.SMPPVersion     */    public void setVersion(SMPPVersion version) throws VersionException {        if (getState() != UNBOUND) {            throw new VersionException("Cannot set SMPP version after binding");        }        if (version == null) {            this.interfaceVersion = SMPPVersion.getDefaultVersion();        } else {            this.interfaceVersion = version;        }    }    /**     * Get the SMPP version in use by this connection. The version in use by the     * connection <b>may </b> be different to that specified before the bind     * operation as binding to the SMSC may result in an alternative SMPP     * version being negotiated. For instance, if the client sends a bind packet     * to the SMSC specifying that it supports SMPP version 3.4 but the SMSC     * returns a bind_resp stating it supports version 3.3, the Connection     * automatically sets it's internal version to use down to 3.3.     */    public SMPPVersion getVersion() {        return interfaceVersion;    }    /**     * Get the current state of the ESME. One of UNBOUND, BINDING, BOUND or     * UNBINDING.     */    public int getState() {        return state;    }

⌨️ 快捷键说明

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