You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
286 lines
7.1 KiB
Java
286 lines
7.1 KiB
Java
// TCPService.java
|
|
|
|
package protocol; // protocol package
|
|
|
|
import java.util.*; // import Java utility classes
|
|
|
|
import support.*; // import Jasper support classes
|
|
|
|
/**
|
|
This is the class for a TCP service entity.
|
|
|
|
@author Iain A. Robin, Kenneth J. Turner
|
|
@version 1.0 (1st September 1999, IAR): initial version
|
|
<br/> 1.4 (9th March 2006, KJT): updated for JDK 1.5
|
|
<br/> 1.5 (26th July 2010, KJT): minor tidying
|
|
*/
|
|
public class TCPService implements ProtocolEntity {
|
|
|
|
/** Debug flag */
|
|
private final static boolean DEBUG = false;
|
|
|
|
// Service primitives (based on Halsall Figs 11.6 - 11.8):
|
|
|
|
/** Active open message */
|
|
public final static String ACTIVE_OPEN = "Active Open";
|
|
|
|
/** Passive open message */
|
|
public final static String PASSIVE_OPEN = "Passive Open";
|
|
|
|
/** Open failure message */
|
|
public final static String OPEN_FAILURE = "Open Failure";
|
|
|
|
/** Open received message */
|
|
public final static String OPEN_RECEIVED = "Open Received";
|
|
|
|
/** Open success message */
|
|
public final static String OPEN_SUCCESS = "Open Success";
|
|
|
|
/** Send message */
|
|
public final static String SEND = "Send";
|
|
|
|
/** Deliver message */
|
|
public final static String DELIVER = "Deliver";
|
|
|
|
/** Close message */
|
|
public final static String CLOSE = "Close";
|
|
|
|
/** Closing message */
|
|
public final static String CLOSING = "Closing";
|
|
|
|
/** Closed message */
|
|
public final static String CLOSED = "Closed";
|
|
|
|
/** Abort message */
|
|
public final static String ABORT = "Abort";
|
|
|
|
/** Push message */
|
|
public final static String PUSH = "(Push)";
|
|
|
|
/** Open confirmed message (internal use) */
|
|
public final static String OPEN_CONFIRMED = "Open Confirmed";
|
|
|
|
// State constants
|
|
|
|
/** Connected state */
|
|
private final static int CONNECTED = 0;
|
|
|
|
/** Calling state */
|
|
private final static int CALLING = 1;
|
|
|
|
/** Listening state */
|
|
private final static int LISTENING = 2;
|
|
|
|
/** Close sent state */
|
|
private final static int CLOSE_SENT = 3;
|
|
|
|
/** Disconnected state */
|
|
private final static int DISCONNECTED = 4;
|
|
|
|
/** Protocol for service */
|
|
private ProtocolEntity provider;
|
|
|
|
|
|
/** Events from provider */
|
|
private Vector<ProtocolEvent> providerEvents;
|
|
|
|
/** Service name */
|
|
private String name;
|
|
|
|
/** Service entity role */
|
|
private int role;
|
|
|
|
/** Protocol state */
|
|
private int state;
|
|
|
|
/** Request Push flag */
|
|
private boolean push;
|
|
|
|
/** Message size */
|
|
private int messageSize;
|
|
|
|
/**
|
|
Constructor for a TCP service entity.
|
|
|
|
@param name service name
|
|
@param role service role
|
|
*/
|
|
public TCPService(String name, int role) {
|
|
this.name = name;
|
|
this.role = role;
|
|
initialise();
|
|
}
|
|
|
|
/**
|
|
Return the TCP service entity name.
|
|
|
|
@return service name
|
|
*/
|
|
public String getName() {
|
|
return (name);
|
|
}
|
|
|
|
/**
|
|
Return the services offered by the entity.
|
|
|
|
@return services offered
|
|
*/
|
|
public Vector<String> getServices() {
|
|
Vector<String> services = new Vector<String>();
|
|
if (state == CONNECTED) { // connected?
|
|
if (!TCP.isSlowStart() || // not slow start and
|
|
name.equals("User A")) { // user A?
|
|
String service = // set send service
|
|
SEND + " " + messageSize + " octets";
|
|
if (push) // push flag set?
|
|
service += " " + PUSH; // append push
|
|
services.addElement(service); // add send service
|
|
}
|
|
if (!TCP.isSlowStart()) // not slow start?
|
|
services.addElement(CLOSE); // add close service
|
|
}
|
|
else if (state == DISCONNECTED) {
|
|
if (role == TCP.SERVER)
|
|
services.addElement(PASSIVE_OPEN);
|
|
else
|
|
services.addElement(ACTIVE_OPEN);
|
|
}
|
|
return (services);
|
|
}
|
|
|
|
/**
|
|
Initialise service entity.
|
|
*/
|
|
public void initialise() {
|
|
providerEvents = new Vector<ProtocolEvent>();
|
|
push = false;
|
|
if (TCP.isSlowStart()) // slow start?
|
|
setState(CONNECTED); // start directly as connected
|
|
else // client-server/peer-peer
|
|
setState(DISCONNECTED); // start as disconnected
|
|
}
|
|
|
|
/**
|
|
Perform entity service.
|
|
|
|
@param service service requested
|
|
@return resulting service events
|
|
*/
|
|
public Vector<ProtocolEvent> performService(String service) {
|
|
Vector<ProtocolEvent> events = new Vector<ProtocolEvent>();
|
|
PDU pdu;
|
|
switch (state) {
|
|
case CONNECTED:
|
|
if (service.startsWith(SEND)) {
|
|
String type = SEND + " (" + messageSize + ")";
|
|
if (service.indexOf(PUSH) > 0)
|
|
type += " " + PUSH;
|
|
pdu = new PDU(type);
|
|
pdu.size = messageSize;
|
|
transmitPDU(pdu, provider);
|
|
events.addElement(
|
|
new ProtocolEvent(ProtocolEvent.TRANSMIT, pdu));
|
|
}
|
|
if (service.startsWith(CLOSE)) {
|
|
pdu = new PDU(CLOSE);
|
|
transmitPDU(pdu, provider);
|
|
events.addElement(
|
|
new ProtocolEvent(ProtocolEvent.TRANSMIT, pdu));
|
|
setState(CLOSE_SENT);
|
|
}
|
|
break;
|
|
case CALLING:
|
|
break;
|
|
case DISCONNECTED:
|
|
if (service.equals(ACTIVE_OPEN)) {
|
|
pdu = new PDU(service);
|
|
transmitPDU(pdu, provider);
|
|
events.addElement(
|
|
new ProtocolEvent(ProtocolEvent.TRANSMIT, pdu));
|
|
setState(CALLING);
|
|
}
|
|
if (service.equals(PASSIVE_OPEN)) {
|
|
pdu = new PDU(service);
|
|
transmitPDU(pdu, provider);
|
|
events.addElement(
|
|
new ProtocolEvent(ProtocolEvent.TRANSMIT, pdu));
|
|
setState(LISTENING);
|
|
}
|
|
break;
|
|
}
|
|
for (Enumeration enumeration = providerEvents.elements();
|
|
enumeration.hasMoreElements(); )
|
|
events.addElement((ProtocolEvent) enumeration.nextElement());
|
|
return (events);
|
|
}
|
|
|
|
/**
|
|
Receive SDU.
|
|
|
|
@param sdu SDU
|
|
@return resulting service events
|
|
*/
|
|
public Vector<ProtocolEvent> receivePDU(PDU sdu) {
|
|
// respond to PDU received from underlying protocol
|
|
Vector<ProtocolEvent> events = new Vector<ProtocolEvent>();
|
|
String sduType = sdu.type;
|
|
if (sduType.equals(OPEN_SUCCESS) || sduType.equals(OPEN_CONFIRMED))
|
|
setState(CONNECTED);
|
|
else if (sduType.equals(OPEN_FAILURE) || sduType.equals(CLOSED))
|
|
setState(DISCONNECTED);
|
|
return (events);
|
|
}
|
|
|
|
/**
|
|
Sets the messageSize attribute of the TCPService object
|
|
*
|
|
@param size The new messageSize value
|
|
*/
|
|
public void setMessageSize(int size) {
|
|
messageSize = size;
|
|
}
|
|
|
|
/**
|
|
Set entity service provider
|
|
|
|
@param provider service provider
|
|
*/
|
|
public void setProvider(ProtocolEntity provider) {
|
|
this.provider = provider;
|
|
}
|
|
|
|
/**
|
|
Set the Push attribute of a service entity.
|
|
|
|
@param push Push value
|
|
*/
|
|
public void setPush(boolean push) {
|
|
this.push = push;
|
|
}
|
|
|
|
/**
|
|
Set the state attribute of a service entity.
|
|
|
|
@param state state
|
|
*/
|
|
public void setState(int state) {
|
|
if (DEBUG)
|
|
System.err.println("state (" + name + "): " + state);
|
|
this.state = state;
|
|
}
|
|
|
|
/**
|
|
Transmit an SDU.
|
|
|
|
@param sdu SDU
|
|
@param destination destination
|
|
*/
|
|
public void transmitPDU(PDU sdu, ProtocolEntity destination) {
|
|
sdu.setSource(this);
|
|
sdu.setDestination(destination);
|
|
providerEvents = destination.receivePDU(sdu);
|
|
}
|
|
|
|
}
|
|
|