receiverbase.java

来自「Logica lastest SMPP API」· Java 代码 · 共 408 行 · 第 1/2 页

JAVA
408
字号
/* * Copyright (c) 1996-2001 * Logica Mobile Networks Limited * All rights reserved. * * This software is distributed under Logica Open Source License Version 1.0 * ("Licence Agreement"). You shall use it and distribute only in accordance * with the terms of the License Agreement. * */package com.logica.smpp;import java.io.IOException;import com.logica.smpp.pdu.HeaderIncompleteException;import com.logica.smpp.pdu.MessageIncompleteException;import com.logica.smpp.pdu.PDU;import com.logica.smpp.pdu.PDUException;import com.logica.smpp.pdu.UnknownCommandIdException;import com.logica.smpp.util.ByteBuffer;import com.logica.smpp.util.NotEnoughDataInByteBufferException;import com.logica.smpp.util.ProcessingThread;import com.logica.smpp.util.Unprocessed;/** * Abstract base class for classes which can receive PDUs from connection. * The receiving of PDUs can be be performed on background within a separate * thread using the <code>ProcessingThread</code> class. * * @author Logica Mobile Networks SMPP Open Source Team * @version 1.2, 01 Oct 2001 * @see Receiver * @see OutbindReceiver * @see Connection * @see Transmitter * @see Session *//*  13-07-01 ticp@logica.com start(), stop(), setReceiveTimeout(),						   getReceiveTimeout(), setTermException(),						   getTermException() made not synchronized;						   receive(long) & receive(PDU) made synchronized						   so the receiver no longer locks up  13-07-01 ticp@logica.com the call to receiveAsync() in run() now enclosed						   in try-finally and the status RCV_FINISHED						   is set in finally block so the finished status						   is now reported correctly even in case of exception  13-07-01 ticp@logica.com some debug lines corrected; some added  08-08-01 ticp@logica.com added support for Session's asynchronous processing capability  23-08-01 ticp@logica.com added async capability exhibited that if more than						   one pdu is read from connection at once (in one						   connection.receive(), the additional ones aren't						   processed. this behaviour was corrected.  23-08-01 ticp@logica.com added yield() to run() to give chance to other						   threads  26-09-01 ticp@logica.com debug code categorized to groups  01-10-01 ticp@logica.com now derived from new ProcessingThread which implements						   the thread related issues; this change allows to focus						   only on the receiving related in the ReceiverBase						   and on the thread management in the ProcessingThread;						   function covered by ProcessingThread removed*/public abstract class ReceiverBase extends ProcessingThread{	/**	 * Timeout for receiving the rest of PDU from the connection.	 * If the rest of PDU isn't receive in time, <code>TimeoutException</code>	 * is thrown.	 *	 * @see TimeoutException	 */	private long receiveTimeout = Data.RECEIVER_TIMEOUT;	/**	 * Method repeatedly called from <code>process</code> method.	 * It's expected that derived classes implement atomic receive of	 * one PDU in this method using ReceiverBase's	 * <code>tryReceivePDUWithTimeout</code> and	 * <code>receivePDUFromConnection</code> methods.	 *	 * @see #tryReceivePDUWithTimeout(Connection,PDU,long)	 * @see ProcessingThread#process()	 * @see ProcessingThread#run()	 */	protected abstract void receiveAsync();	private byte messageIncompleteRetryCount = 0;	/**	 * This method should try to receive one PDU from the connection.	 * It is called in cycle from <code>tryReceivePDUWithTimeout</code> until	 * timeout expires. The method should check if the actualy received	 * PDU is equal to the <code>expectedPDU</code>.	 *	 * @param connection  the connection from which the PDU should be received	 * @param expectedPDU the command id and sequence id of the received PDU	 *                    should be equal to those of expectedPDU	 * @return the received PDU if any or null if none received	 *	 * @exception IOException exception during communication	 * @exception PDUException incorrect format of PDU	 * @exception TimeoutException rest of data not received for too long time	 * @exception UnknownCommandIdException PDU with unknown id was received	 * @see #tryReceivePDUWithTimeout(Connection,PDU,long)	 * @see #receiveAsync()	 * @see #run()	 * @see PDU#equals(Object)	 */	protected abstract PDU tryReceivePDU(Connection connection, PDU expectedPDU)	throws UnknownCommandIdException,		   TimeoutException,		   PDUException,		   IOException;	/**	 * This is an implementation of <code>ProcessingThread</code>'s	 * <code>process</code> method, which is method called in loop from	 * the <code>run</code> method.<br>	 * This simply calls <code>receiveAsync</code>.	 */	public void process()	{		receiveAsync();	}	/**	 * Calls <code>tryReceivePDUWithTimeout(Connection,PDU,long)</code> with	 * timeout set by <code>setReceiveTimeout</code>.	 *	 * @param connection  the connection from which the PDU should be received	 * @param expectedPDU the command id and sequence id of the received PDU	 *                    should be equal to those of expectedPDU	 * @param timeout     the timeout indication	 * @return the received PDU if any or null if none received	 *	 * @exception IOException exception during communication	 * @exception PDUException incorrect format of PDU	 * @exception TimeoutException rest of data not received for too long time	 * @exception UnknownCommandIdException PDU with unknown id was received	 * @see #tryReceivePDUWithTimeout(Connection,PDU,long)	 */	final protected PDU tryReceivePDUWithTimeout(Connection connection, PDU expectedPDU)	throws UnknownCommandIdException,		   TimeoutException,		   PDUException,		   IOException	{		return tryReceivePDUWithTimeout(connection,expectedPDU,getReceiveTimeout());	}	/**	 * For specified time tries to receive a PDU from given connection by	 * calling method <code>tryReceivePDU</code>.	 * The method <code>tryReceivePDU</code> must be implemented in the derived	 * class.	 * <p>	 * The timeout can be either value > 0, then it means for	 * how many milliseconds will be repeatedly tried to receive a PDU.	 * If the timeout is = 0 then there is only one attempt to receive a PDU.	 * If the timeout is equal to Data.RECEIVE_BLOCKING, then the this method	 * tries receive a PDU until it is received.	 *	 * @param connection  the connection from which the PDU should be received	 * @param expectedPDU the command id and sequence id of the received PDU	 *                    should be equal to those of expectedPDU	 * @param timeout     the timeout indication	 * @return the received PDU if any or null if none received	 *	 * @exception IOException exception during communication	 * @exception PDUException incorrect format of PDU	 * @exception TimeoutException rest of data not received for too long time	 * @exception UnknownCommandIdException PDU with unknown id was received	 * @see #tryReceivePDU(Connection,PDU)	 * @see PDU#equals(Object)	 */	final protected PDU tryReceivePDUWithTimeout(Connection connection, PDU expectedPDU, long timeout)	throws UnknownCommandIdException,		   TimeoutException,		   PDUException,		   IOException	{		debug.write(DRXTX,"receivePDU: Going to receive response.");		long startTime = Data.getCurrentTime();		PDU pdu = null;		if (timeout == 0) {			// with no timeout try just once			pdu = tryReceivePDU(connection, expectedPDU);		} else {			// with timeout keep trying until get some or timeout expires			while ((pdu == null) && canContinueReceiving(startTime, timeout)) {				pdu = tryReceivePDU(connection, expectedPDU);			}		}		if (pdu != null) {			debug.write(DRXTX,"Got pdu "+pdu.debugString());		}		return pdu;	}	/**	 * Elementary method receiving data from connection, trying to create

⌨️ 快捷键说明

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