J-Sim INET Tutorial

A Simple Two-host, One-router and One-TCP-Connection Example

March 20, 2006

Figure 1: The scenario constructed in this example


Step 1. Creating the network topology

Step 1. 1. We create a component directory to hold all the components created in this example:

cd [mkdir drcl.comp.Component /example2]

Step 1.2.  We create the network topology:

puts "Create network topology..."
set link_ [java::new drcl.inet.Link]
$link_ setPropDelay 0.3; # 300 ms
set adjMatrix_ [java::new {int[][]} 3 {{1} {0 2} {1}}]
java::call drcl.inet.InetUtil createTopology [! .] $adjMatrix_ $link_

Step 2. Configuring the nodal structure and the attributes at the bottleneck link

Step 2.1. We use drcl.inet.NodeBuilder to configure the internal structure of nodes

puts "build..."
# NodeBuilder:
set rb [mkdir drcl.inet.NodeBuilder .routerBuilder]
$rb setBandwidth 1.0e7; #10Mbps
set hb1 [cp $rb .hostBuilder1]
set hb2 [cp $rb .hostBuilder2]
[mkdir drcl.inet.transport.TCP $hb1/tcp] setMSS 512
mkdir drcl.inet.transport.TCPSink $hb2/tcpsink
$rb build [! n1]
$hb1 build [! h0]
$hb2 build [! h2]

In the above script, we use the RUV command "cp" to copy the router node builder to two host builders. As a result, the bandwidth set in the router builder is also copied to those in the host builders.

The internal structures of hosts h0, h2, and router n1 are shown in Figures 2 and 3. The core service layer of the end hosts is the same as that shown in Figure 3 of Example 1, while that of the router node is shown in Figure 3.  Note that the node builder will include appropriate default components in the core service layer according to the network topology and the other protocols in the node. For example, a rt component (drcl.inet.core.RT) will be included in csl if the node has more than one interface, or one of the ports exported by the rt component (i.e., .service_rt@, .rt_ucast@, .rt_mcast@; see Figure 5 in the INET tutorial page) has been requested for connection (by the other protocol components).

Figure 2 The internal structure of end hosts constructed in this example.

 

Figure 3 The internal structure of the router node constructed in this example.
NOTE: Since J-Sim v1.2, the default CSL composition combines the queue and network interface into one QueueNI component.

Step 2.2.  We set up the TCP source and sink at node 0 and node 1 respectively:

puts "Set up tcp's/applications..."
! h0/tcp setPeer 2

set src_ [mkdir drcl.inet.application.BulkSource h0/source]
$src_ setDataUnit 512
connect -c $src_/down@ -and h0/tcp/up@

set sink_ [mkdir drcl.inet.application.BulkSink h2/sink]
connect -c $sink_/down@ -and h2/tcpsink/up@

Sidebar: Node Map

Alternatively, we may use "node map" as in the following script to replace step 2.1 and 2.2:

set nb [mkdir drcl.inet.NodeBuilder .nodeBuilder]
$nb setBandwidth 1.0e7; #10Mbps
$nb build [! n1]
$nb build [! h0] {
tcp drcl.inet.transport.TCP
source -/tcp drcl.inet.application.BulkSource
}
$nb build [! h2] {
tcpsink drcl.inet.transport.TCPSink
sink -/tcpsink drcl.inet.application.BulkSink
}
! h?/tcp* setMSS 512
! h?/s* setDataUnit 512

Node map is a string that describes the protocols and applications to be included in a node and the connections between them.  Each line in a node map corresponds to a protocol or an application, and the syntax is as follows:

<id>    <port/lower_layer_protocol_id>    <class_name>

<id> and <class_name> determines the protocol/application while <port/lower_layer_protocol_id> determines which other protocol this protocol/application should be connected to.  If the protocol is known to INET (if drcl.inet.InetUtil.getPID(Component) returns a positive protocol ID), then the second field can be omitted like tcp and tcpsink in the above script.

In the current implementation, the component <lower_layer_protocol_id> must be defined ahead.  For example, if we switch the tcp line and the source line, NodeBuilder will give a warning and stop building the node.  The csl component (core service layer) is pre-defined, so we can use it without defining it.  For example, the tcp line can also be written as:

tcp    6/csl   drcl.inet.transport.TCP

The protocols/applications are connected at the down@ port and the <port>@up port.  If <port> is specified as "-" like source and sink in the above script, then the up@ port is used.  So in this example, source/down@ is connected with tcp/up@ and sink/down@ is connected with tcpsink/up@.

Step 2.3. We configure the bottleneck bandwidth and buffer size at interface 1 of node 1:

! n1 setBandwidth 1 1.0e4; # 10Kbps at interface 1
! n1 setBufferSize 1 6000; # ~10 packets at interface 1

Here we call  the drcl.inet.Node.setBandwidth(int interfaceIndex_, double bandwidth_) method and the setBufferSize(int interfaceIndex_, double bufferSize) method. The interface index is determined in the adjacency matrix.

Step 2.4. We set up static route between hosts h0 and h2 using drcl.inet.InetUtil.setupRoutes(...):

puts "Set up static routes..."
java::call drcl.inet.InetUtil setupRoutes [! h0] [! h2] "bidirection"

The drcl.inet.InetUtil.setupRoutes(...) method has the following forms:

void setupRoutes (Node src_, Node dest_)
void setupRoutes (Node src_, Node dest_, String bidirect_)
void setupRoutes (Component src_, Component dest_, long destAddr_, long destAddrMask_)
void setupRoutes (Component src_, Object[] dest_, long destAddr_)
void setupRoutes (Component src_, Object[] dest_, long destAddr_, long destAddrMask_)
void setupRoutes (Component src_, Object[] dests_, long srcAddr_, long srcAddrMask_,
long destAddr_, long destAddrMask_)

The second form is used in this example. The last three are used to set up shortest path multicast trees.

Step 2.5. We set up a TrafficMonitor component and a Plotter component (as shown in Figure 4) to on-line keep track of  the instantaneous throughput, the sequence numbers of packets received, the size of the congestion window, and the smoothed RTT.

Figure 4.  How the TrafficMonitor component and the Plotter component are used in this example.

puts "Set up TrafficMonitor & Plotter..."
set plot_ [mkdir drcl.comp.tool.Plotter .plot]
set tm_ [mkdir drcl.net.tool.TrafficMonitor .tm]
connect -c h2/csl/6@up -to $tm_/in@
connect -c $tm_/bytecount@ -to $plot_/0@0
connect -c h0/tcp/cwnd@ -to $plot_/0@1
connect -c h2/tcpsink/seqno@ -to $plot_/0@2
connect -c h0/tcp/srtt@ -to $plot_/0@3

The TrafficMonitor (.tm) component counts incoming packets and generates byte count events in bit/second. The Plotter (.plot) component creates plots for data that arrive at different ports. The port created at the plotter is of the format of "x@y" where x is the index of the data set and y is the index of the plot. The x-axis of each plot is in the unit of time (second). In this example, the plotter creates four plots, each of which contains one data set.

Sidebar: Save Plotter Results for Offline Viewing

The plotter can also be used to save the results to a file.  One can use this feature to view the results offline by adding the following lines after creating the plotter:

set file_ [mkdir drcl.comp.io.FileComponent .file]
$file_ open "your_file_name.plot"; # assign your file name here
connect -c $plot_/.output@ -to $file_/in@
setflag plot false $plot_

After the simulation is complete, one can view the results by:

java drcl.comp.tool.Plotter <file_name>

To better manipulate the figures (set title, x/y labels, export to EPS files), one may start a J-Sim terminal and then type in the following commands:

set plot [mkdir drcl.comp.tool.Plotter plot]
$plot load <file_name>

Then use the published methods of the Plotter component to manipulate the figures:

fill(int plotID_)	// Fill the plot in the window.
repaint(int plotID_) // Repaint the plot.
exportEPS(int plotID_, String epsFileName_)
addLegend(int plotID_, int dataset_, String legend_)
setLegend(int plotID_, int dataset_, String legend_)
setTitle(int plotID_, String title_)
setXLabel(int plotID_, String xlabel_)
setXLog(int plotID_, boolean on_)
setXRange(int plotID_, int min_, int max_)
setYLabel(int plotID_, String ylabel_)
setYLog(int plotID_, boolean on_)
setYRange(int plotID_, int min_, int max_)

Acknowledgment: The Plotter component is a wrap-up of the Ptplot tools from the Ptolemy II system, a product of the Ptolemy project in the Department of Electrical Engineering and Computer Sciences of the University of California at Berkeley.

Step 2.5.  We set the garbage flag of the n1 component to on-line keep track of the packets dropped at the bottleneck link.

setflag garbagedisplay true recursively n1

The syntax of the command is as follows:

setflag <flags>... <enabled> ?recursively? <path>... 

The setflag command  sets/resets  the flags specified in <flags> in the components/objects specified by <path>, where the valid values for <flags> are Trace, Garbage, GarbageDisplay, Debug, ErrorNotice, and EventExport.  If "recursively" is given, the command is recursively applied to all the inner components of the component specified by <path>.

Note that for the purpose of component-level debugging and monitoring, each component in J-Sim is equipped with an information port, or infoport.  Four types of information may be exported at the infoport: Trace, Garbage, Debug, and ErrorNotice.  Also, a component can also export events at event ports whenever there is a state change in the component.  The command setflag is used to turn on/off the exporting operations.  For example, when the Garbage flag is set,  the component exports the discarded data at the infoport whenever the component discards data, and if one wants the discarded data to be displayed for debugging purpose, one should turn on the GarbageDisplay flag. Turning on the GarbageDisplay flag implies turning on the Garbage flag. Turning off the Garbage flag imples turning off the GarbageDisplay flag.

Also note that the infoports of all the components are connected to a RUV system monitor component which is then responsible for outputting whatever it receives to the Tcl terminal.

Step 3.  Starting the Simulation

Step 3.1. We attach the simulation runtime and conduct the simulation for 100 seconds:

# Attach the simulator runtime
attach_simulator .
puts "simulation begins..."
run .
rt . stopAt 100

Several points are in order:

rt . stop		Stops the simulation right away.
rt . stop <time> Stops the simulation at current_time + <time>.
rt . stopAt <time> Stops the simulation at <time>.
rt . resume Resumes the simulation.
rt . resumeFor <time> Resumes the simulation for <time> and then stops.
rt . resumeTo <time> Resumes the simulation and then stops at <time>.

In the example, we stop the simulation at time 100 seconds.

Results:  After executing the above script, three windows pop up and display on the fly the instantaneous throughput, congestion window size, the sequence number of packets received, and the smoothed RTT, respectively.  These parameters are continuously updated. 

Also, the packets that are dropped are logged  in the terminal:

GARBAGE| 9.297688000000003| /example2/n1/csl/q1/| sz562(INET)sz20--src:#0--dest:#2--prot:6--TTL:2/255--ToS:#0__<sz542(TCP)sz30--s:0--d:0--seq13312--AWND:0--TS8.996788800000003__<EMPTY_BODY>__>__| exceeds capacity
GARBAGE| 9.747288000000003| /example2/n1/csl/q1/| sz562(INET)sz20--src:#0--dest:#2--prot:6--TTL:2/255--ToS:#0__<sz542(TCP)sz30--s:0--d:0--seq14336--AWND:0--TS9.446388800000003__<EMPTY_BODY>__>__| exceeds capacity
GARBAGE| 10.196888000000003| /example2/n1/csl/q1/| sz562(INET)sz20--src:#0--dest:#2--prot:6--TTL:2/255--ToS:#0__<sz542(TCP)sz30--s:0--d:0--seq15360--AWND:0--TS9.895988800000003__<EMPTY_BODY>__>__| exceeds capacity
GARBAGE| 80.00406559999988| /example2/n1/csl/q1/| sz562(INET)sz20--src:#0--dest:#2--prot:6--TTL:2/255--ToS:#0__<sz542(TCP)sz30--s:0--d:0--seq76800--AWND:0--TS79.70316639999989__<EMPTY_BODY>__>__| exceeds capacity

The source code of this example is available here. We have also validated our classes by comparing the simulation results obtained here against those obtained in ns-2.  The results are in extremely good agreement.


In summary, we have shown in this example that:

  1. How to include a protocol (e.g., TCP) in NodeBuilder and alternatively, how to use "node map" to build a node.
  2. How to configure the bandwidth and the buffer size on an interface of a node.
  3. How to establish static routes between a source node and a sink node using drcl.inet.InetUtil.setupRoutes(...).
  4. How to keep track of, and display on the fly, network parameters of interest using drcl.net.tool.TrafficMonitor and drcl.comp.tool.Plotter.
  5. How to instruct a component to export information (e.g., packets that have been discarded) by using the setflag command.

Where we go next

Example 3: multiple-host, two-router and multiple-TCP connections.