// TCPMedium.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 medium. @author Iain A. Robin, Kenneth J. Turner @version 1.0 (1st September 1999, IAR): initial version
1.4 (9th March 2006, KJT): updated for JDK 1.5
1.5 (26th July 2010, KJT): minor tidying; a loss rate has been introduced for medium messages */ public class TCPMedium extends Medium { /** Message loss rate (0.2 means 20% of messages are lost) */ private float lossRate = 0.2f; /** Random number index */ private int randomIndex; /** Random numbers */ private Vector randomNumbers; /** Constructor for a TCP medium. */ public TCPMedium() { super(); // construct superclass randomNumbers = new Vector(); // initialise random numbers } /** Initialise the medium. */ public void initialise() { super.initialise(); randomIndex = 0; // initialise random index } /** Gets the matching PDU. @param description PDU description @return matching PDU */ protected PDU getMatchingPDU(String description) { // identify and return PDU currently on channel with // type and parameters matching those described in given string TCPMessage tcpdu; // try to match PDU type and seq with a PDU currently on channel: for (Enumeration enumeration = pdus.elements(); enumeration.hasMoreElements(); ) { tcpdu = (TCPMessage) enumeration.nextElement(); if (description.indexOf(tcpdu.getID()) > 0) return (tcpdu); } return (null); // no match found } /** Return a list of strings describing actions (services) that can be carried out in the current state. @return service descriptions */ public Vector getServices() { Vector list = new Vector(); // initialise service list HashSet pdusSent = // initialise list of sources new HashSet(); for (Enumeration enumeration = pdus.elements(); // go through PDUs enumeration.hasMoreElements(); ) { PDU pdu = (PDU) enumeration.nextElement();// get next PDU if (pdu != null) { // non-null PDU? String name = pdu.getSource().getName();// get PDU source name String description = // get PDU id and name pdu.getID() + " [" + name + "]"; if (!pdusSent.contains(name)) { // no PDU with this source? pdusSent.add(name); // add source to list list.addElement( // add delivery service "Deliver " + description + " - no loss"); } if (random() < lossRate) // loss is possible? list.addElement( // add loss service "Lose " + description + " - congestion/error"); } } return(list); // return service list } /** Return a random float. If the list of randoms contains an unused value then use this, otherwise generate a fresh value and add to the list. This allows random numbers to be generated consistently when simulation steps are undone/redone. @return random number in the range (0..1] */ private float random() { if (randomIndex < randomNumbers.size()) // index within list? return( // return this random ((Float)randomNumbers.elementAt(randomIndex++)).floatValue()); else { // index not within list Float random = new Float(Math.random()); // get random number randomNumbers.addElement(random); // add random to list randomIndex++; // increment list index return(random.floatValue()); // return rand number } } /** Set the medium loss rate. @param lossRate loss rate */ public void setLossRate(float lossRate) { this.lossRate = lossRate; // set loss rate } }