📄 smsclink.java
字号:
package ie.omk.smpp.net;import ie.omk.smpp.message.SMPPPacket;import ie.omk.smpp.util.APIConfig;import ie.omk.smpp.util.PropertyNotFoundException;import ie.omk.smpp.util.SMPPIO;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.EOFException;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * Abstract super class of all classes that implement a network link to the * SMSC. This class uses buffered input and output internally for reading and * writing to whatever input/output streams the concrete implementation provides * it. Sending and receiving are guarded against multiple-thread access. That * is, if more than one thread attempts to write packets to the link, they will * not get "mixed" in the output stream. Likewise on read, only one thread will * receive an incoming packet. * * @author Oran Kelly * @version $Id: SmscLink.java 302 2006-08-10 20:36:40Z orank $ */public abstract class SmscLink { private static final String TIMEOUT_UNSUPPORTED_ERR = "Timeout not supported"; private static final String END_OF_STREAM_ERR = "EOS reached. No data available"; private static final String LINK_NOT_UP_ERR = "Link not established."; private static final Log LOGGER = LogFactory.getLog(SmscLink.class); /** The buffered input of the link. */ private BufferedInputStream in; /** The buffered output of the link. */ private BufferedOutputStream out; /** Object to use to lock reading. */ private final Object readLock = new Object(); /** Object to use to lock writing. */ private final Object writeLock = new Object(); /** Incoming bytes snoop stream. */ private OutputStream snoopIn; /** Outgoing bytes snoop stream. */ private OutputStream snoopOut; /** * Set to automatically flush the output stream after every packet. Default * is true. */ private boolean autoFlush; /** * Create a new unconnected SmscLink. */ public SmscLink() { try { autoFlush = APIConfig.getInstance().getBoolean( APIConfig.LINK_AUTO_FLUSH); } catch (PropertyNotFoundException x) { autoFlush = true; } finally { if (LOGGER.isDebugEnabled()) { LOGGER.debug("autoFlush set to " + autoFlush); } } } /** * Open the connection to the SMSC. Calling this method will cause the * network link to the SMSC to be established. Once this method returns an * application may bind to the SMSC to begin it's SMPP session. * * @throws java.io.IOException * If an exception occurs while opening the connection. */ public final void open() throws java.io.IOException { implOpen(); int inSize = -1; int outSize = -1; APIConfig cfg = APIConfig.getInstance(); inSize = getBufferSize(cfg, APIConfig.LINK_BUFFERSIZE_IN); outSize = getBufferSize(cfg, APIConfig.LINK_BUFFERSIZE_OUT); if (LOGGER.isDebugEnabled()) { LOGGER.debug("IN buffer size: " + inSize); LOGGER.debug("OUT buffer size: " + outSize); } if (inSize < 1) { this.in = new BufferedInputStream(getInputStream()); } else { this.in = new BufferedInputStream(getInputStream(), inSize); } if (outSize < 1) { this.out = new BufferedOutputStream(getOutputStream()); } else { this.out = new BufferedOutputStream(getOutputStream(), outSize); } } private int getBufferSize(APIConfig cfg, String propName) { int size = -1; try { String s = cfg.getProperty(propName); if (s.toLowerCase().endsWith("k")) { size = Integer.parseInt(s.substring(0, s.length() - 1)) * 1024; } else if (s.toLowerCase().endsWith("m")) { size = Integer.parseInt(s.substring(0, s.length() - 1)) * 1048576; } else { size = Integer.parseInt(s, 10); } } catch (PropertyNotFoundException x) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Buffer size is not set in configuration: " + propName + ", using default."); } } catch (NumberFormatException x) { LOGGER.warn("Bad value for config property " + propName, x); } return size; } /** * Implementation-specific link open. This method will be called by the * {@link #open} method. This method is responsible for establishing the * underlying network connection to the remote SMSC system. For example, The * TCP/IP implementation would create and connect a new * <code>java.io.Socket</code> to the SMSC host. * * @throws java.io.IOException * If an exception occurs while opening the connection. */ protected abstract void implOpen() throws java.io.IOException; /** * Close the connection to the SMSC. Calling this method will close the * network link to the remote SMSC system. Applications should be unbound * from the SMPP link (using {@link ie.omk.smpp.Connection#unbind}) before * closing the underlying network link. The connection may be reestablished * using {@link #open}. * * @throws java.io.IOException * If an exception occurs while closing the connection. */ public final void close() throws java.io.IOException { out = null; in = null; implClose(); boolean autoClose = true; try { autoClose = APIConfig.getInstance().getBoolean( APIConfig.LINK_AUTOCLOSE_SNOOP); } catch (PropertyNotFoundException x) { LOGGER.debug(APIConfig.LINK_AUTOCLOSE_SNOOP + " property not found. Using the default of " + autoClose); } if (autoClose) { try { if (snoopOut != null) { snoopOut.close(); } if (snoopIn != null) { snoopIn.close(); } } catch (IOException x) { LOGGER.warn("Exception while closing snoop streams.", x); } } else { try { if (snoopOut != null) { snoopOut.flush(); } if (snoopIn != null) { snoopIn.flush(); } } catch (IOException x) { LOGGER.warn("Exception while flushing snoop streams.", x); } } } /** * Implementation-specific link close. This method is called by the * {@link #close}method after ensuring no further writes or reads can * occur. Note that any threads that are writing, reading or blocked on * either the readLock or writeLock at the moment this method is called will * still execute. Only further reads or writes will be disallowed. An * implementation should completely close the underlying network link to the * remote SMSC system but it should not free any resources that will * preclude the {@link #open}method from reconnecting. * * @throws java.io.IOException * if an exception occurs during close. * @see #getInputStream * @see #getOutputStream * @see #close */ protected abstract void implClose() throws java.io.IOException; /** * Send a packet to the SMSC. * * @param pak * the SMPP packet to send. * @param withOptional * true to send the optional parameters over the link too, false * to only send the mandatory parameters. * @throws java.io.IOException * if an exception occurs during writing or if the connection is * not open. */ public void write(SMPPPacket pak, boolean withOptional) throws java.io.IOException { if (out == null) { throw new IOException(LINK_NOT_UP_ERR); } synchronized (writeLock) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -