?? receiverbase.java
字號:
/*
* 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 org.smpp;
import java.io.IOException;
import org.smpp.pdu.PDU;
import org.smpp.pdu.HeaderIncompleteException;
import org.smpp.pdu.MessageIncompleteException;
import org.smpp.pdu.PDUException;
import org.smpp.pdu.UnknownCommandIdException;
import org.smpp.util.ByteBuffer;
import org.smpp.util.ProcessingThread;
import org.smpp.util.Unprocessed;
import org.smpp.util.NotEnoughDataInByteBufferException;
/**
* 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 $Revision: 1.4 $
* @see Receiver
* @see OutbindReceiver
* @see Connection
* @see Transmitter
* @see Session
*/
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;
private byte messageIncompleteRetryCount = 0;
/**
* 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();
/**
* 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
* @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
* PDU from them and buffering data in case the PDU
* isn't still complete. It has timeout checking for incomplete
* messages: if the message isn't received completly for certain time
* and no new data are received for this time, then exception is thrown
* as this could indicate communication problem.
*
* @param connection the connection to receive the data from
* @return either PDU, if complete received or null
*
* @exception IOException exception during communication
* @exception PDUException incorrect format of PDU
* @throws TimeoutException rest of data not received for too long time
* @throws UnknownCommandIdException PDU with unknown id was received
* @see Connection
* @see Unprocessed
*/
final protected PDU receivePDUFromConnection(Connection connection, Unprocessed unprocessed)
throws UnknownCommandIdException, TimeoutException, PDUException, IOException {
debug.write(DRXTXD2, "ReceiverBase.receivePDUFromConnection start");
PDU pdu = null;
ByteBuffer buffer;
ByteBuffer unprocBuffer;
try {
// first check if there is something left from the last time
if (unprocessed.getHasUnprocessed()) {
unprocBuffer = unprocessed.getUnprocessed();
debug.write(DRXTX, "have unprocessed " + unprocBuffer.length() + " bytes from previous try");
pdu = tryGetUnprocessedPDU(unprocessed);
}
if (pdu == null) { // only if we didn't manage to get pdu from unproc
buffer = connection.receive();
unprocBuffer = unprocessed.getUnprocessed();
// if received something now or have something from the last receive
if (buffer.length() != 0) {
unprocBuffer.appendBuffer(buffer);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -