FHTW Berlin

FHTW Berlin
Fachbereich 4
Internationale Medieninformatik
PROG1: Programmierung I
Wintersemester 02/03


Laboratory 2: Systems of Objects; Nodes and Channels


You should read through this entire assignment before you begin.

Preparing for the Lab

1. Experiment with the application.

This week's laboratory project involves a network routing simulation.  In the simulation, routers (nodes) send and receive packets (pieces of information) to each other along various routes (channels).  The nodes could be computers, for instance, sending and receiving information from each other across the internet.  This problem set could be a scaled down (very scaled down) version of a commercially available product.  Have a look at the simulation by downloading nodenet.jar and cs101.jar, starting a new project called nodenet in JBuilder, adding the .jars as libraries, selecting nodenet.Main as the main class, and pressing the start icon.

The idea of the simulation is to experiment with various network configurations and empirically determine their behaviors. In other words, play with the application and see what happens. When the GUI pops up, you will see two panels, side by side. The panel on the right, which is currently empty, is where all of the simulations will take place. The panel on the left contains the available GUI elements -- all nodes, in this case. Above both panels are three menus: File, Simulation, and Selection. To use the simulator in the most basic way, you first construct a network and then set it in motion. The necessary steps are described below.

One of the main things you need in a simulator are nodes. In order to add a node to your simulator, select one of the nodes from the panel on the left, then click on the drawing panel to place it somewhere. There are three types of nodes which appear when you first run the program:

To remove an element, click on it and then select Remove from the Selection menu.

The other crucial element in a simulator are channels. Channels run from one node to another, and are represented by a black line with an arrow, connecting the two nodes. In order to add a channel to your simulator, double click on the first node, then click on the second node. Channels have directions: they go from the node you start with to the node you end with. It is possible to have more than one channel between two nodes (e.g., one in each direction), but this isn't drawn particularly well. To remove a channel, outline the channel's arrow by clicking on it, then select Remove from the Selection menu.

To start objects moving through the demo, select Start from the Simulation menu. You can pause the simulation using Pause.  You can dynamically add elements while the simulation is running. You can also temporally disable a node or channel by selecting it and then choosing the Disable command from the Selection menu. To re-enable an element, use Enable. Using the Remove option to physically remove an element from the network while the simulation is running is discouraged; deletion is provided only for creating a new network, not for dynamically changing network behavior.

Experiment with the network for a few minutes. Can you get the channels to fill up? A channel is displayed in red if it is full. Can you create any other interesting behaviors? Remember that you can disable channels (using the Selection menu) while the simulation is running. You may want to keep a record of your experiments to compare your later results with. (Such a record should include both network topology (how things are connected) and dynamic behavior (what you did, what it did).) You can even save any particularly interesting network configurations using the Save As option under the File menu.

We have provided two types of connecting nodes.  The first, and the one you have been using (Default Connecting Node), uses a DefaultNodeBehavior.  The other type of connecting node you can load is IntermediateNodeBehavior.  To run a node with the IntermediateNodeBehavior, try adding

as an application parameter. In the GUI elements panel, you will see this fourth type of node.  Can you discern any differences between the IntermediateNodeBehavior and the DefaultNodeBehavior?  What advantages, if any, does one enjoy over the other?

2. Design your code.

In this lab, you're going to create your own behavior for a Node. You will do this by creating a class that implements NodeBehavior. You may want to look at the code for the NodeBehavior interface now. What methods will you have to implement?

package nodenet;

// Importe
import nodenet.InputChannelVector;
import nodenet.OutputChannelVector;

public abstract interface NodeBehavior {

// Methoden
void transmitPacket(InputChannelVector p0, OutputChannelVector p1);
}

Your NodeBehavior class will not be a Runnable; instead it will be called by a Node, which is Runnable and has its own Thread. The Node's run method also contains the while(true) loop. (Node also implements the graphical user interface (GUI) for a node.) The heart of Node's run method looks something like this:

Since transmitPacket( ) will be called from inside a while( true ) loop, you only have to handle one object at a time.

Note that transmitPacket( ) takes in two arguments. The first argument is an InputChannelVector; the second argument is an OutputChannelVector. Both InputChannelVector and OutputChannelVector are essentially Vectors. A vector is a dynamic collection of things of the same type that we can access using a common name, just like Arrays. If myVector is a vector, I can access the first element of myVector as myVector.elementAt(0). Note that Java always begins counting at 0. You can find more information about Vectors on Java's Documentation pages.

Now InputChannelVector and OutputChannelVector don't just contain Objects (we say a "Vector of Objects"), they contain one or more InputChannels an OutputChannels as appropriate (e.g., InputChannelVector being a "Vector of InputChannels").

Each InputChannel from the first argument, the InputChannelVector, has the following method:

    public Object readObject()
        throws ChannelEmptyException, ChannelDisabledException;
This lets you read the objects coming at you down this particular input channel. You only need to read one packet from one input channel on each time around the interactive control loop, though. Note that a given input channel may be empty or disabled, in which case it will throw an appropriate exception. If you haven't found exceptions in a book yet, don't worry. If you get everything else to work, start investigating exceptions.

The second argument to transmitPacket( ) is an OutputChannelVector. Any active non-full output channel would be a good place to put any packet you may have picked up. As a corollary to InputChannel, OutputChannel has

But be careful: when an output channel is full, it will throw an exception if you try to write to it. Make sure that you don't drop any packets if this happens, or write packets that don't exist.

The main piece of your job is to implement the transmitPacket( )method of NodeBehavior. This method should take an object off an InputChannel from inputChannels (using readObject()) and feed it to an OutputChannel in outputChannels (using writeObject()). Remember that you may have multiple InputChannels and OutputChannels, and that some of them may be disabled..

There are several ways that you can choose the input and output channels from their respective Vectors. Think of at least two, and record these strategies. The more creative you can be, the more interesting your lab will be. You should design code for at least one of these strategies, and ideally for more than one.

You should be aware that both InputChannelVector and OutputChannelVector contain a method, size(), which returns the size of the Vector; additionally, both contain a method, isEmpty, which returns True if the Vector is empty.

Additionally, InputChannelVector contains three more methods:

OutputChannelVector contains the same three methods listed above, except that each method returns an OutputChannel instead of an InputChannel.

One of the main points of this lab is to observe the effects of different strategies on the behavior of your network as a whole. Is your strategy fair? Does it drop packets? Create them? Do packets cluster in certain parts of your network? Can you come up with a strategy that behaves differently?

Some utilities that you might want to use:

returns an int between 0 and range, inclusive. You can refer to it as MoreMath.randomInt if you include the line import cs101.util.*; at the top of your file. causes the current Thread to sleep for millis milliseconds. This allows you to put delays in your nodes. Warning: You will have to catch the exception, though you don't necessarily have to do anything with it.

If you have other ideas, design them and then ask us about them.

3. Handle exceptions.

Channels occasionally throw exceptions. You need to be concerned about these: Once you get your intermediate node to work, if you still have time, make sure that your code is robust to these exceptions, and does not lose objects. You can find more about exceptions on the Java pages: Formal description - tutorial "What's an Exception and Why Do I Care?".

Building your code.

Your job in the lab is to implement one or more node behaviors, to test these behaviors on your own examples, and to exchange example networks with other students in the class.  During lab, we will create a shared repository of test networks.  Test data development should be pooled, and sharing of test data is encouraged. Discussion of why networks behave as they do is strongly encouraged.  Talk to the people next to you to get good ideas for test networks. If you need help loading another student's test network, please ask me to show you how.

Begin the lab by implementing a node behavior. You will need to define a new class, say MyClass. What should you call the file it's defined in? What does it need to extend or implement? What methods does it have? (Remember that the interactive control loop is already defined for you, but it expects to be able to call your transmitPacket() method with two arrays.

The first lines of your file, before your class definition, will need to say:

Also, you should be sure that your class is public.

Once your code compiles, you should try running it. To run your code, you will need to supply the name of your node behavior class to nodeNet. You can do this by entering it on the application parameters form in the properties menu:

(assuming that MyClass is the name of your class)

You can now test your code using a network you have saved.  It is probably best to use a very simple network first -- if you don't have a simple one saved, you might want to create one now.

Once you have this network running, try some others.  See if you can find one that stumps your code. (Try to fix it, or at least to understand why. Can you design another network to stump your code?)

Don't forget to tell me about your cool networks in class, so that I can use them, too :)

Let's re-cap:

The post-lab is due by the beginning of your next lab!


This course is an adaption for the Fachhochschule für Technik und Wirtschaft , Berlin by Prof. Dr. Debora Weber-Wulff of a part of Prof. Dr. Lynn Andrea Stein's Rethinking CS101 project produced while she was at the MIT AI Lab belonging to the Department of Electrical Engineering and Computer Science (EECS) at the Massachusetts Institute of Technology. The copyright for all materials belongs to Lynn Andrea Stein, this adaptation is used by permission. All rights reserved.
A textbook is in preparation by Morgan Kaufmann Publishers


Questions or comments: <weberwu@fhtw-berlin.de>