26th January 2002

VirtualNet 2

virtualnet screen capture

VirtualNet2 is an application that simulates a network on a standalone computer.

A CORBA application -by introducing one line of code before initializing the ORB- uses automatically the VirtualNet: it is hosted on one of the virtual computers, and its communications with other CORBA objects are only possible as far as there is any valid virtual path to its host.

It works with any application CORBA, and with any ORB implementing interceptors. I have succesfully used it with the Sun ORB included with JDK1.4, Orbacus 4 and Jacorb 1.4. The application is written in Java, but the application using the virtual net can be written on any language, provided it has a CORBA mapping.


This application is the evolution of VirtualNet, an application I designed in 1997 to be able to simulate a network topology on a single computer. Using most of the communication systems, being sockets, JavaRMI, CORBA, etc, allows the testing of the application on just one computer, but this test lacks the problems that happen on real cases on a network, like:

  • Slower communications: delays
  • Problems on links, giving way to unreachable nodes

On the first approach, VirtualNet only worked with JavaRMI, replacing the rmiregistry. It had its own compiler, parallel to the rmic compiler, to create stubs and skeletons that intercepted the communications, and checked when that communication was possible and which delay had it associated. Although the approach was quite transparent, the application still had to change slightly the code, but the main drawback was that JavaRMI applications not using the registry could not take advantage of the application. And I never tried to change the application to simulate the more advanced capabilities included in JavaRMI with Java2.

VirtualNet2 works only over CORBA, using interceptors. It has two parts, the server, written in Java, which creates the virtual net. It has a nice graphical interface, lets the user to modify the virtual net on any moment, and listens on a specific port for virtual paths checking. The protocol to check for virtual paths is very simple, easy to implement on any language.

The client part is so far written on Java, but I'm now written as well a C++ client. The interesting client is a CORBA interceptor that automatically accesses the VirtualNet to verify wether the target node is reachable or not. If it's not reachable, a CORBA COMM_FAILURE exception is raised, simulating completely the real case behaviour. This checking is done twice: when the remote object is accessed, and when the answer is sent.

Create a virtual net

The server program is conceptvnet2.VirtualNetconcept, which can be invoked (attention to the classpath) as:

java vnet2.VirtualNet
This application has several command line
Use [-help] [-nograph] [-verbose] [-port=xxx] file

The -nograph option is interesting to launch existing virtual nets without a graphical interface.

To create a virtual net, it is needed to give a port, where it will listen for client requests. At any moment, the graphical interface lets the user save or load any other virtual net.

To create nodes, links, etc, there is currently just one possibility: go to NetLayout->Modify, and introduce an string with the modifications. I have been working on a nice interface to make it easier, but I really find the current input quite flexible. For example, to create a node 'A', a node 'B', and a link '1' between them, the input is:


Following are the sintactic rules:

  1. A node or a link is specified by a string that contains no spaces or any of the following characters: '-', '+', '<', '>', '(', ')','/'
  2. A node is created by prepending the character '+' to the name of the node. For example: +Machine_1
  3. To remove a node, the same notation as to created is used, but using the character '-'. For example -Machine_1
  4. A node can de activated/deactivated temporary using '+.' or '-.' For example -.Machine_1
  5. A link is created specifying '+', the first node, then a character '<', the link id, again a character '>' and then the second node. For example: +Machine_1<link1>Machine_2. To do the link unidirectional, use '<' before the second node: +Machine_1<link1<Machine_2
  6. A link is removed specifying '-<' before the node name, like -<link1
  7. A link can de activated/deactivated temporary using '+.' or '-.;. For example -.<link1
  8. delays (in millseconds) can be specified to nodes or links by appending to its name "(delay)", on creation. For example: +Node(100) or +Node<Link(100)>OtherNode
  9. A node delay can be changed using /node(delay), like in /node(100)
  10. A link delay can be changed using /<link(delay), like in /<link(100)
  11. The delay for every link can be changed using /<(delay), like /<(100)
  12. Every node delay can be changed using /(delay), like in /(100)
  13. In the previous cases, if the delay is not specified, default values are assumed
  14. For example:

    + A + B + C + D + E + A<1>B + A<5>D + B<2>C
    + B<10>E + E<11>D + C<3>D + C<20<E

    Creates the next layout:

    original layout

    It is possible to move around the nodes and the links, to get a clearer picture:

    moved layout

    Using the mouse, it is possible to activate / deactivate or destroy the nodes and links. Following are the used icons:

    Node active Node deactivated Node in use
    Link active Link deactivated Link in use
    Link mono active Link mono deactivated Link mono in use

    Use the virtual net

    The server program is located in the package vnet2, but not so the client side. There are several reasons for it. The first is that any application can use the virtual net as a client, and the second one, that the client does not have to be written in Java

    Said this, the package vnet2user contains a client that implements the interceptor behaviour for CORBA.

    On Java, the ORB is usually initialized with:

    ORB orb = ORB.init(args, props);

    Where args are the command line arguments and props the list of properties, as a java.util.Properties. Before doing this step, it can be written:

    args=vnet2user.Interceptor.setup(user, args, props);

    This method installs the interceptor, using some of the arguments. It expects the following arguments:

    • -virtualHostName: the name of the virtual host where this ORB is to be simulated. It must exist on the virtual net, and it is mandatory.
    • -virtualNetHost: the name of the host containing the virtual net. It is the local host by default
    • -virtualNetPort: the port where the virtual net is installed. It is mandatory

    When the interceptor reads the arguments, it returns another list of arguments where the virtualNet arguments are excluded. If some of the mandatory parameters is not present, the program is executed without using the virtual net.

    The first argument for setup is an object implementing the interface vnet2user.InterceptorUser, which receives any message from the interceptor. It can be null, but in that case any error is dumped on the normal output, and the program exited.

    The distribution includes a client/server program, a counter, showing the use of this interceptor.

    Another interceptor for C++ will be included shortly.

    Client protocol

    Note that this section is not needed to use the application

    The package vnet2user includes as well a program called TestClient that shows the client protocol. This program requires a virtual host name, and then verifies wether there is a virtual path to any other host.

    The VirtualNet server listens continuosly on a port, where the client can request wether a virtual path is possible. This path is calculated every time, applying the delays that have been specified for each node and link: this process can be observed on the screen, as the icons change their colour.

    To work, the virtualNet server stablishes a session for each client:

    1. It receives the name of the node to host; this node is specified as an array of bytes, holding the first byte the number of bytes to read. The node name must be in UTF-8 format: byte?order specified by a mandatory initial byte-order mark.
    2. A byte is returned. Return value can be 0 to indicate success or FF to indicate error. In this case, a return value of FF means that the node given is not existing in the current netlayout. This is not a real error, further requests are still valid.
    3. After this session is started, each new request must just contain the target node, and the return value will indicate wether there is a virtual path bertween both nodes or not.
    4. The format for the request is the same as for the session creation, now including just the target node name (UTF-8...)
    5. The return value contains 0 if a path exists and FF if not. This specification can change to show some extended information about the error. For example FE could mean that there is no virtual path because the target node does not exist, etc. Anycase, a value 0 will always means success and any other value is an error flag

    Version and bugs

    Current version is 0.3; it works without problems, although it contains some minor errors that I will solve as soon as possible:

    • If a node is destroyed, its links are destroyed as well. But if there is a monodirectional link to the node, that link stays, and must be destroyed separately. The server is still able to calculate correctly paths, it is only the screen that looks bad
    • Once a server is shutdown (virtualnet is closed), if a new one is going to be created, the applications keeps on asking if the current virtual net (which one?) must be saved.
    • It does not update the display on the Swing thread, resulting in refresh problems. This is the most awful problem (at least it does not always appear).
    • The interceptors does not behave correctly if the VirtualNet server is shutdown.

    In addition, the C++ interceptor will be included with the next version.

    License and download

    VirtualNet2 is delivered as it, without any responsabilities on the author. It is open source, it can be used or modified without any limitations. If some bug is found or the behaviour is not as expected, please send me a mail (java_lmp@yahoo.co.uk) and I will promptly introduce the modifications. The task is distributed with source, and therefore you can make by your own any changes.

    There are three downloadable files (plus another three on the example section):

    • Source code. It includes the packages vnet2, vnet2user, and the counter example. To compile, please use the JDK 1.4, with the option -source 1.4. It is in .zip format (57 KB): vnet2.zip
    • vnet2 binary code (.jar file, 111 KB): vnet2.jar. It includes a manifest file it is possible to start the server using:
      java -jar vnet2.jar
    • vnet2user binary code (.jar file, 11 KB): vnet2user.jar


    To see the following example, it is required to download the jar files shown on the previous section, plus the following 2 files:

    You can download as well the source for the example (9 KB): counter.zip.

    The first step is to start the virtual net server. This can be done with:

    java -jar vnet2.jar example.vnet

    This should show a netlayout like the shown before, with some nodes and links deactivated. This example uses the port 3456.

    Now, the server of the example is started. Please introduce the next info (just one line), which contacts with the virtual net on the port 3456, and simulates the server on the node E. An additional argument is given, with the name of the server (a file is written with this name containing the server's reference).

    java -classpath vnet2.jar:vnet2user.jar:counter.jar counter.Server
         -virtualHostName E -virtualNetPort 3456 ServerExample

    One or more clients can now be started. Please introduce the next info (just one line), which contacts with the virtual net on the port 3456, and simulates the client on the node A. An additional argument is given, with the name of the server.

    java -classpath vnet2.jar:vnet2user.jar:counter.jar counter.Client
         -virtualHostName A -virtualNetPort 3456 ServerExample

    On the layout given, I have included long delays; for this reason, any request can take much longuer than expected. It is possible to see on the screen the events on the net; try to deactivate any node or link to check that the client receives indeed the appropiated exception. Note on the source code that no special adaptations have been added (only the already mentioned one-line setup).