org.web3d.vrtp.net
Class DatagramStreamBuffer

java.lang.Object
  |
  +--org.web3d.vrtp.net.DatagramStreamBuffer
All Implemented Interfaces:
NetworkCommBadge, java.lang.Runnable

public class DatagramStreamBuffer
extends java.lang.Object
implements java.lang.Runnable, NetworkCommBadge

DatagramStreamBuffer This is a reusable class for reading datagrams from a socket, in a platform-independent way.

The DatagramStreamBuffer reads and stores datagrams (NOT PDUs). Since this is a fairly generic operation, this should be a very reusable class. It implements the runnable interface, and generally runs in its own thread, reading data from the socket as rapidly as datagrams come in. When no datagrams are arriving, the thread blocks on the receive() method of the socket class, consuming no CPU resources.

BehaviorStreamBuffer and others can act as an adaptor to DSB, utilizing this object's generic capability to provide PDUs to higher level objects.

This uses the security classes, which provide transparent browser-independent access to things outside the sandbox. Note that use of these security classes isn't particularly secure. Since they are declared as public interfaces and classes, a rougue class can also seize them and bypass security. We live with this, since our primary objective right now is to make security go away and stop hurting us, rather than having it protect us.

Location: ~/org/web3d/vrtp/net/DatagramStreamBuffer.java Web: http://www.web3d.org/WorkingGroups/vrtp/org/web3d/vrtp/net/DatagramStreamBuffer.java

Author:
Don McGregor (mcgredo@nps.navy.mil), Don Brutzman (brutzman@nps.navy.mil)
See Also:
mil.navy.nps.dis.BehaviorStreamBuffer, SecurityStrategy

Field Summary
(package private)  java.util.Vector datagramBuffer
          Holds datagrams received recently
(package private)  int datagramPort
           
(package private)  java.net.InetAddress multicastAddress
           
(package private)  boolean readingActive
           
protected  SecurityStrategy strategy
          platform-specific security strategy
(package private)  int ttl
           
(package private)  boolean usingMulticast
           
 
Constructor Summary
DatagramStreamBuffer()
          Unicast constructor: create a new unicast DSB on an ephemeral port (a port picked by the system).
DatagramStreamBuffer(int pDatagramPort)
          Unicast constructor: construct a new unicast datagram socket on the given port.
DatagramStreamBuffer(java.lang.String pMulticastAddress, int pDatagramPort)
          Multicast constructor: given a multicast address and a port number, create a socket that is joined to that group on that port number.
 
Method Summary
 void cleanup()
          Closes down sockets nicely
 void createMulticastSocket(java.net.InetAddress pMcastAddress, java.lang.Integer pPort)
          Create a multicast socket on a given port.
protected static void debug(java.lang.String pDiagnostic)
          Debugging output.
 void doRun()
          doRun loops, reading packets and adding them to the list of recieved packets, until readingActive is set to false.
protected  void finalize()
          Finalize method--used to clean up any sockets that are still open
 int getDatagramPort()
          returns the port used by this socket
static boolean getDEBUG()
          Returns the status of debugging output, true = on
 java.net.InetAddress getMulticastAddress()
          Returns the multicast address used by this socket
 java.util.Vector getPackets()
          Returns a vector of datagrams that have been received by this object since the last time this method was called.
 boolean getReadingActive()
          Returns the run status
 boolean getUsingMulticast()
          returns true of this is using multicast to communicate
static void main(java.lang.String[] args)
          For testing purposes.
 void openEphemeralUnicastSocket()
          Creates ephemeral unicast datagram socket, on a port picked by the system.
 void openUnicastSocket(java.lang.Integer pPortNumber)
          Creates unicast datagram socket.
 void resumeReading()
           
 void run()
          run() switches on platform-secific security, then calls doRun, which does the actual work of reading from the network.
 void sendDatagram(java.net.DatagramPacket pDatagram)
          Sends out a datagram.
 void sendDatagram(java.net.DatagramPacket pDatagram, java.net.InetAddress pDestinationHost, int pDestinationPort)
           
 void sendDatagram(java.net.DatagramPacket pDatagram, java.lang.String pDestinationHost, int pDestinationPort)
          Sends out a datagram to the designated destination and desitnation port.
 void sendStoredDatagram()
          A hack.
static void setDEBUG(boolean pDEBUG)
          Turns on or off debugging output
 void setReadingActive(boolean pState)
           
 void setTimeToLive(int pTTL)
          This is JDK 1.2 specific code; if you have problems compiling under 1.1, this is probably the cause.
 void setTTL(byte pTTL)
          Set the multicast socket time-to-live.
 void stopReading()
          When this is set to false, the run() loop will terminate.
protected static void trace(java.lang.String pDiagnostic)
          Guaranteed debugging output.
 
Methods inherited from class java.lang.Object
, clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

datagramPort

int datagramPort

multicastAddress

java.net.InetAddress multicastAddress

ttl

int ttl

usingMulticast

boolean usingMulticast

datagramBuffer

java.util.Vector datagramBuffer
Holds datagrams received recently

readingActive

boolean readingActive

strategy

protected SecurityStrategy strategy
platform-specific security strategy
Constructor Detail

DatagramStreamBuffer

public DatagramStreamBuffer(int pDatagramPort)
Unicast constructor: construct a new unicast datagram socket on the given port.

DatagramStreamBuffer

public DatagramStreamBuffer()
Unicast constructor: create a new unicast DSB on an ephemeral port (a port picked by the system).

DatagramStreamBuffer

public DatagramStreamBuffer(java.lang.String pMulticastAddress,
                            int pDatagramPort)
Multicast constructor: given a multicast address and a port number, create a socket that is joined to that group on that port number.
Method Detail

getDEBUG

public static boolean getDEBUG()
Returns the status of debugging output, true = on

setDEBUG

public static void setDEBUG(boolean pDEBUG)
Turns on or off debugging output

debug

protected static void debug(java.lang.String pDiagnostic)
Debugging output. Pass in a string, and it gets printed out on the console. You can pass in strings such as "foo " + bar.getName().

trace

protected static void trace(java.lang.String pDiagnostic)
Guaranteed debugging output. Pass in a string, and it gets printed out on the console. You can pass in strings such as "foo " + bar.getName().

getMulticastAddress

public java.net.InetAddress getMulticastAddress()
Returns the multicast address used by this socket

getDatagramPort

public int getDatagramPort()
returns the port used by this socket

getUsingMulticast

public boolean getUsingMulticast()
returns true of this is using multicast to communicate

openUnicastSocket

public void openUnicastSocket(java.lang.Integer pPortNumber)
Creates unicast datagram socket. This should be called by the appropriate security strategy first; eg, the constructor calls the security strategy, which, after the appropriate security calls have been made, calls this. Passes in datagramPort indirectly.

openEphemeralUnicastSocket

public void openEphemeralUnicastSocket()
Creates ephemeral unicast datagram socket, on a port picked by the system. This should be called by the appropriate security strategy, eg the constructor calls the security strategy, which in turn calls this after turning on approprate security calls.

createMulticastSocket

public void createMulticastSocket(java.net.InetAddress pMcastAddress,
                                  java.lang.Integer pPort)
Create a multicast socket on a given port. The port is passed in via the instance variable "datagramPort". The multicast address to be joined is also passed in as an instance variable "parameter".

stopReading

public void stopReading()
When this is set to false, the run() loop will terminate.

resumeReading

public void resumeReading()

getReadingActive

public boolean getReadingActive()
Returns the run status

setReadingActive

public void setReadingActive(boolean pState)

run

public void run()
run() switches on platform-secific security, then calls doRun, which does the actual work of reading from the network.

This is the implementation of the runnable interface. The two-step process--run calls SecurityStrategy's invokePrivilege(), which in turn calls back to this object--is required because some platforms require the security calls to be "above" in the stack. Just switching on the security parameters in strategy, and then returning and attempting to read from a socket, is not enough.

Specified by:
run in interface java.lang.Runnable

doRun

public void doRun()
doRun loops, reading packets and adding them to the list of recieved packets, until readingActive is set to false. In the course of events the receivedDatagrams() method will usually be called, which grabs the vector of recieved datagrams and replaces it with a new, empty vector.

Called by run(); this is the essential portion of the run loop. run() has enabled platform-specific security at this point, so doRun doesn't have to worry about network sandboxes.


getPackets

public java.util.Vector getPackets()
Returns a vector of datagrams that have been received by this object since the last time this method was called.

setTimeToLive

public void setTimeToLive(int pTTL)
This is JDK 1.2 specific code; if you have problems compiling under 1.1, this is probably the cause. JDK 1.2 introduced an int rather than a byte when setting the time-to-live on a socket; the setTTL(byte) method was deprecated in preference to the setTimeToLive(int) method. This just brings the code in line with the current practice. To make this work under 1.1, just comment out all of this method, recompile, and use the setTTL method instead. Set the multicast socket time-to-live. 15=> local distribution, 63=>regional distribution, 127=>global distribution.

setTTL

public void setTTL(byte pTTL)
Set the multicast socket time-to-live. 15=> local distribution, 63=>regional distribution, 127=>global distribution. It seems that there is a bug under NS 4.04 (surprise, surprise) so that setTTL on the mcast socket throws an exception, so you probably shouldn't use this yet. JDK 1.2 deprecated the setTTL method on the MulticastSocket class and replaced it with the setTimeToLive method, which takes an int instead of a byte. If you have problems compiling under 1.1 this is probably the problem.

sendDatagram

public void sendDatagram(java.net.DatagramPacket pDatagram,
                         java.lang.String pDestinationHost,
                         int pDestinationPort)
Sends out a datagram to the designated destination and desitnation port. This is a unicast send, which requires a machine name and port name to send the datagram to.

Parameters:
pDatagram - datagram being sent out
pDestinatinHost - place being sent to, in string format, either name or dotted decimal
pDestinationPort - the port to be sent to on the remote machine

sendDatagram

public void sendDatagram(java.net.DatagramPacket pDatagram,
                         java.net.InetAddress pDestinationHost,
                         int pDestinationPort)

sendStoredDatagram

public void sendStoredDatagram()
A hack. This is only for internal used but must be declared public so it can be accessed from the security packages.

sendDatagram

public void sendDatagram(java.net.DatagramPacket pDatagram)
Sends out a datagram. The destination should already have been set by the time it gets to this point.

cleanup

public void cleanup()
Closes down sockets nicely

finalize

protected void finalize()
                 throws java.lang.Throwable
Finalize method--used to clean up any sockets that are still open
Overrides:
finalize in class java.lang.Object

main

public static void main(java.lang.String[] args)
For testing purposes. Opens up a socket on the designated address and port, and listens for datagrams, storing them up. if you get datagrams, things are working. This also serves as an example of how to use the class.