
DatagramReader |
ptolemy.actor.lib.net.DatagramReader |
This actor reads datagram packets via a separate thread. The thread
responds to datagrams whenever they arrive, giving the actor the ability
to read the datagrams asynchronously.
Datagrams are connectionless, open-loop internet communications. Each
datagram packet contains data plus a return address. The return
address consists of an IP address and a socket number. Datagrams use
the UDP protocol under which no reply or confirmation is expected.
This is in contrast to TCP which expects confirmations and attempts to
deliver packets in order to the layer above TCP. This can result in
long delays in the delivery of information across the network. Because
UDP makes no such attempts, it never hangs and does not need to be timed out.
<p>NOTE: This actor has been developed to work in the Discrete Event
(DE) and Synchronous Data Flow (SDF) domains. Use elsewhere with
caution.
<p> <p>The simplest scenario has the thread constantly stalled
awaiting a packet. When a packet arrives, the thread quickly queues
it in one of the buffers of the actor, calls the
getDirector().fireAtCurrentTime(), and then stalls again awaiting the
next packet. By stalling again and again, the thread keeps the actor
aware at all times of incoming packets. This is particularly
important if packets come in more quickly than the model can process
them. Depending on the domain (e.g. DE) in which this actor is used,
the director may respond to the fireAtCurrentTime() call of the thread by
calling the fire() method of the actor. In this case, fire() then
broadcasts the data received, along with the return address and return
socket number from which the datagram originated.
<p>The data portion of the packet is broadcast at the <i>output</i> port.
The type of the output is always an array of bytes.
<p>The return address and socket number are broadcast as String and int
respectively. These tell where the received datagram originated from.
<p>The behavior of the actor under less simple scenarios is governed by
parameters of this actor. Additional packet(s) can arrive while the
director is getting around to calling fire(). Conversely, the
director may make extra calls to fire(), even before any datagrams
have come in. I call these the eager packet and eager director
scenarios respectively.
<p>Background: There are two packet buffers. The thread and the fire()
method share these buffers and maintain consistency via synchronization
on the object <i>_syncFireAndThread</i>. This synchronization prevents
conflicts when accessing the shared buffers and when accessing the
count of queued packets.
<p>The <i>overwrite</i> parameter applies to the eager packet
scenario. Setting this parameter to true is useful in cases where it
is possible for data to come in too fast for the model to process.
This setting alleviates data gluts without undue loss of data when the
model is able to keep up. When <i>overwrite</i> is set to true (the
default), the actor discards the packet already received in
favor of the new packet. If false, the new packet is queued behind the
existing one. In the latter case, both buffers are now full. The
thread then waits for fire() to consume a queued packet before it
stalls again awaiting the next. In all other cases (<i>overwrite</i>
true or no queued packets) the thread immediately stalls to await the
next packet.
<p>The <i>blockAwaitingDatagram</i> parameter applies to the eager
director case. This case comes up most often in SDF, where an actor
is expected to block in fire until an output can be produced. If
true, a call to fire() will block unless or until a datagram has
arrived. If false, then fire() returns without waiting, using the
<i>defaultOutput</i> parameter in place of real data. The
<i>returnAddress</i> and <i>returnSocketNumber</i> ports have default
outputs as well, but they are not parameter-programmable.
<p>
<p>NOTE: This actor has a parameter <i>localSocketNumber</i> for the port
number assigned to its local datagram socket. Initially, the local
socket number is set to 4004. There is no particular reason for choosing
this number, except that is noticeable in the code and in Vergil, thus
encouraging you to change it to any desired value in the range 0..65535.
Note that socket numbers 0..1023 are generally reserved and numbers 1024 and
above are generally available.
<p>Some commonly used port numbers (a.k.a. socket numbers) are shown below:
<pre>
Well-known Ports
(Commonly Used Ports)
7 (Echo)
21 (FTP)
23 (TELNET)
25 (SMTP)
53 (DNS)
79 (finger)
80 (HTTP)
110 (POP3)
119 (NNTP)
161 (SNMP)
162 (SNMP Trap)
</pre>
Reference: http://192.168.1.1/Forward.htm
(A webpage hosted from within the Linksys BEFSR41 Cable/DSL Router)
<p>NOTE: This actor can also be configured to handle multicase datagram
socket. A MulticastSocket is a DatagramSocket with additional capabilities
to join groups of other multicast hosts on the internet. A multicast group
is specified by a class D IP address and a standard UDP port number.
When one member sends a packet to a multicast group, all recipients
subscribing to that host and port receive the packet.
Currently, The parameter <i>defaultReturnAddress</i> is overloaded to specify
a multicast datagram IP address. When the return address is a multicast IP
address, The parameter <i>localSocketNumber</i> is used to specify the
UDP port number for the multicast group. A multicast IP address
ranges from 224.0.0.0 to 239.255.255.255, inclusive. To send a packet to the
group, the sender can be either a DatagramSocket or a MulticastSocket. The
only difference is that MulticastSocket allows you to control the time-to-live
of the datagram. Don't use 224.0.0.1 ~ 224.255.255.255 when the live time of
is specified larger than 1.
<p>FIXME: we might not want to overload the <i>defaultReturnAddress</i> and
the <i>localSocketNumber</i> parameter...
<p>Another useful tidbit is the command 'netstat'. This works in a
DOS prompt and also in the UNIX-like Bash shell. In either shell,
enter 'netstat -an'. This command shows current port allocations! Ports
allocated to Ptolemy models are shown along with other port allocations.
Other useful network commands include 'ping' and 'tracert'.
Both TCP and UDP (datagram) ports are shown by netstat.
FIXME: Find out whether a TCP port using a specific number blocks a
UDP port from using that same number.
Author(s): Winthrop Williams, Joern Janneck, Xiaojun Liu, Edward Lee
(Based on TiltSensor actor written
by Chamberlain Fong, Xiaojun Liu, Edward Lee)
Version:$Id: DatagramReader.doc.html,v 1.1 2006/02/22 18:40:26 mangal Exp $
Pt.Proposed Rating:Yellow (winthrop)
Pt.Accepted Rating:Yellow (winthrop)
returnAddress
This port outputs the IP address portion of the received
datagram packet. The type of this output is String. This is
the IP address of the remote datagram socket which sent the
packet to the socket of this actor. Under IPv4, this string has
the familiar form "128.32.1.1". This output defaults (when no
datagram has been received and blocking is false) to the IP
address of the socket.
returnSocketNumber
This port outputs the socket (a.k.a port) number portion of the
received datagram packet. The type of this output is int.
This is the socket number of the remote datagram socket which
sent the packet to this actor's socket. This is an integer in
the range 0 through 65535. This output defaults (when no
datagram has been received and blocking is false) to this
actor's local socket number.
output
This port outputs the data portion of the received datagram
packet. The type of <i>output</i> may depend on the datagram
received, which may vary even during a single run of a model.
<b>The user is encouraged to play with the configuration of
this port</b> to best suit the need at hand.
trigger
The trigger input port reads and discards a token from each
channel that has a token. The type of this port has been set
to GENERAL, permitting any token type to be accepted. The
hasToken() and get(int) methods are called on this input, but
their contents are discarded. The presence of a connection to
this input serves a purpose by causing the director to
schedule the firing of this actor at an appropriate place in
the sequence of firings of actors. This is particularly
useful in the SDF domain. Without a trigger input, the SDF
scheduler would be unable to schedule a firing of this actor
unless it can be scheduled as the first actor to be fired.
Thus, without this input, configurations in SDF would be
limited. (@See ptolemy.actor.lib.Source for an archetypal
trigger input.)
localSocketNumber
This actor's local socket (a.k.a. port) number. <b>This is a
system resource allocated to this actor.</b> No other actor
with the same local socket number may run at the same time.
Currently, When the return address is a multicast IP address,
this parameter is also used to specify the UDP port number
for the multicast group.
actorBufferLength
Length (in bytes) of each of the actor's two packet buffers for
receiving a datagram. This length does not include the bytes
needed for storing the datagram's return address and other
housekeeping information. This buffer need only be big enough
to hold the payload (a.k.a. data portion) of the datagram.
platformBufferLength
Length (in bytes) of the buffer within java and/or the
platform layers below java. Java documents refers to all this
collectively as the platform. The size of this buffer is
controlled via the getReceiveBufferSize() and
setReceiveBufferSize() methods. @see java.net.DatagramSocket.
Caution #1 - The platform treats setReceiveBufferSize() as a
suggestion only. It supposedly reports the actual buffer size
granted in subsequent calls to getReceiveBufferSize().
However, my experiments with this showed it granting buffers
as large as 2 gigabytes, with no apparent limit except the
maximum representable integer value. Thus, I suggest taking
this with a grain of salt. Caution #2 - the
get/setReceiveBufferSize() calls block when called as long as
another thread is in a receive() call on that same socket.
This is undocumented in Java's documentation. Also note that
the setReceiveBufferSize() method is not available in early
JDK's, which makes it important to have
setPlatformBufferLength set to false when generating code.
setPlatformBufferLength
Determine whether the platformBufferLength parameter will be
used to set the platform's receive buffer size. This
parameter must contain a boolean token, and has a default of
false.
overwrite
Whether to overwrite when inundated with datagrams or let
them pile up. Default is true. If false, datagrams will
queue up (mostly in the platform, some in the actor). The
datagram used at each invocation of fire will be the oldest in
the queue. On the other hand, if <i>overwrite</i> is true,
then minimal queuing will occur and the most recent data will
be used when fire() is called. Older data will be discarded.
blockAwaitingDatagram
Whether to block in fire(). If fire() is called before the
datagram has arrived, the actor must either block awaiting the
datagram or use its <i>defaultOutput</i>. This blocking
parameter controls which choice fire() will make. This
parameter is useful for SDF models, where it is generally set
to true. It has no effect in DE models unless the trigger
input has been connected. Type is Boolean. Default value is
true.
defaultReturnAddress
The default for the <i>returnAddress</i> output. This token is
broadcast when the actor is fired, but no actual datagram
is available to broadcast and <i>blockAwaitingDatagram</i> is
false. If blocking were true, the actor would simply stall in
fire() until a datagram arrives. Type is string. Default value
is "localhost".
Currently, this parameter can be overloaded to specify a multicast
datagram IP address. A multicast IP address ranges from
224.0.0.0 to 239.255.255.255, inclusive.
defaultReturnSocketNumber
The default the <i>returnSocketNumber</i> output. This token is
broadcast when the actor is fired, but no actual datagram
is available to broadcast and <i>blockAwaitingDatagram</i> is
false. If blocking were true, the actor would simply stall in
fire() until a datagram arrives. Type is integer. Default
value is 0.
defaultOutput
The default for the <i>output</i> output. This default token
is broadcast when the actor is fired, but no actual datagram
data is available to broadcast and
<i>blockAwaitingDatagram</i> is false. If blocking were true,
the actor would simply stall in fire() until a datagram
arrives. Type is defined by the expression entered. Default
type & value is the integer 0.