WMich Home

 

CS Home

 

Ajay Gupta's Home

 

CS555 Home
Class Policies  & Syllabus
Topics Covered
Home Work I
Home Work II
Home Work III
Home Work IV
Home Work V
Home Work VI
 
 
 
 
 
Message  Board
Class List
Reading List

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Email webmaster

 

 

 

 

CS 555 - Computer Networks

HW5

Spring 2005

Last updated 28-Mar-2005

UPDATES: hw5SourceFiles.zip, tester class compiler error fix help1and RMI fix with SDK1.4 help2

Given March 08, 2005

Due : March 17, 2005 (11:00am) - Extended to March 22, 2005 (11:00am) - Design Specs

             March 29 April 5, 2005 (11:00am) - complete

  NOTE: I MAY UPDATE IT AS NECESSARY. WHAT I HAVE SO FAR SHOULD BE ENOUGH FOR YOU TO COMPLETE THE ASSIGNMENT, HOWEVER.

Reliable Data Transfer Protocol Implementation

A Sliding Window Data Transfer Protocol

Introduction

This assignment deals with achieving reliable data transfer over LRD network channels. An LRD channel can lose, reorder and duplicate messages in transit, subject to a maximum message lifetime; that is, a message sent into an LRD channel can be received at zero or more instants within the maximum message lifetime of its send. You are provided a specification of the data transfer service and a specification of the LRD network layer service. You are to implement a protocol that provides the data transfer service using the LRD service. Your protocol must be based on the sliding window mechanism. You will also need to implement the AIMD algorithm to adapt your window size. You can choose the particulars of the design, including message types and their formats, sequence number space, data block size, retransmission policy, acknowledgment (cumulative and/or selective) policy, round-trip time estimator, etc.

Your grade in this assignment is primarily based on your protocol's correctness , that is, whether it achieves reliable data transfer. Although you could get by with a very restricted protocol (e.g., window size of 1, a fixed window  size, etc.) in this assignment, such a protocol will not have good flexibility. So you should develop a sufficiently general  protocol. You have about 3 weeks for this assignment.

Specifically, the assignment consists of two interacting programs, a Source  and a Sink, as shown in figure 1. The Source consists of three components: SourceTester, SW_Source and NetworkSocket. The Sink consists of three components: SinkTester, SW_Sink and NetworkSocket. SW_Source and SW_Sink represent the transport entities, SourceTester and SinkTester represent their users, and the pair of NetworkSocket represent the network entities, providing the LRD channels. You are to implement SW_Source  and SW_Sink. We provide the other entities.

Figure 1

Figure 1

Network Layer Service

  Class NetworkSocket provides the LRD channels to be used by the  transport entities to communicate with each other. Use it instead of the usual sockets (because in a LAN environment the provided channels display hardly any loss, reordering or duplication). Import NetworkSocket.java file to use instead of the provided channels.

A NetworkSocket object is a "wrapper" to a standard socket object.  Incoming packets (i.e., packets received from the Internet) addressed to the standard socket are immediately passed up to the local transport entity. Outgoing packets (i.e., packets generated by the local transport entity) are buffered in a outgoing packet queue, subject to loss, reordering, duplication and delay before being passed to the underlying standard socket for sending to the remote socket. The extent of loss, reordering and duplication depends  on probability parameters which can be set on the fly (important for testing).  The delay between sending packets depends on a parameter that reflects the available bandwidth; this also can be set on the fly (important for testing).

[Note: In this particular implementation, the LRD errors for a message  are decided when the message enters the socket, that is, when a packet is sent into NetworkSocket, the packet is either dropped, or inserted at some position in the outgoing packet queue, or duplicated and the various  copies inserted into various positions in the outgoing queue. Messages with size bigger than msgMaxSize (defined inside class NetworkSocket) are discarded without notice.]

Public methods of Class NetworkSocket:

  • Constructor NetworkSocket( int aLocalPort, String remoteDN, int aRemotePort)
    Creates the LRD service socket at local site (a corresponding entity would be created at the remote site). Parameters are as follows: aLocalPort is the local port number; remoteDN as the name of the remote host; aRemotePort is the remote port number;
     
  • Method public int send( byte[] data, int len )
    Constructs a network packet containing the data and sends it out on the outgoing LRD channel. (In the current implementation, the packet is subjected to loss, reordering and/or duplication, and inserted in the outgoing packet queue; at some later point the packet(s) is sent into the Internet.) The network packet is of class NetworkPacket (analogous to DatagramPacket).
     
  • Method public void receive(DatagramPacket dp, int timeout) throws IOException, InterruptedIOException
    Checks if a network packet has been received from incoming LRD channel. If a packet is available for reception within timeout value, it passes the received packet to the caller in parameter dp, which must have a buffer of max packet size in caller memory space. If no packet is available for reception within duration timeout, it throws exception InterruptedException. Upon any other IO error, it throws with exception IOException; you do not need to exit on this error, unless it happens frequently.
     
  • Method  public int getMsgMaxSize()
    Gets message maximum size. NetworkSocket class discards messages with size bigger than msg max size without notice.
     
  • Method public void close()
    Closes the socket.
Comments:
  • The loss, reordering and duplication probabilities can be varied during execution. You may want to first fix them at zero for debugging purposes.  Given a pair of peer NetworkSocket objects, the probability and bandwidth  parameters can be different in each object, i.e., different for each direction.  For debugging purposes, you may want to set the errors to zero in one direction.

    The same considerations apply to the inverse bandwidth.

    DO NOT USE ANY OTHER METHOD IN CLASS NetworkSocket. THEY ARE SUBJECT TO CHANGE.

Data Transfer Service

You are to implement two classes, SW_Source and SW_Sink, that provide reliable  byte stream transfer to their users, SourceTester and SinkTester,  and interact only via the LRD channels defined above.

Class SW_Source implements the following public methods:

  • Data variable:  SourceTester dtsource;
    Pointer to the class that created object of class SW_Source.
     
  • Constructor SW_Source( local port, remote domain name and port, send buffer size ) in the following format:
    SW_Source (int aLocalPort, String aRemoteDN, int aRemotePort, int aBufSize);
    Constructs the source part of a sliding window data transfer protocol (it would have send window, counters, timers, etc.).  The send buffer size is constant and indicates the number of bytes that SW_Source must be prepared to buffer; this, together with the ackData(n) calls (described below), allows the user to know the number of bytes that it (the user) can foist on SW_Source.
  • Method public void sendData( byte[] data);
    Accepts byte string from local user (for example, SourceTester) to be transferred to remote user (for example, SinkTester). This method does  not block and should be called only when SW_Source has space to buffer the  data. If there is no space to buffer the data, it throws an error (using  throw new Error("buffer is full")). Note that this method only transfers  the data from the user to SW_Source buffer. It does not wait for this data  to be sent to the remote site (non-blocking function).
  The user of SW_Source (i.e., Class SourceTester) implements the following method:
  • Method public void ackData(int n);
    SW_Source calls this method to indicate that "n" bytes of data have been acked. This allows the user to know how much data is still outstanding and how much more data it can pass to SW_Source.
Class SW_Sink implements the following methods:
  • Data variable:  SinkTester dtsink;
    Pointer to the class that created object of class SW_Sink.
  • Constructor SW_Sink( local port, remote domain name and port, receive buffer size ) in the following format:
    SW_Sink (int aLocalPort, String aRemoteDN, int aRemotePort, int aBufSize );
    Constructs the sink part of a sliding window data transfer protocol (it would have send window, counters, timers, etc.).  The receive buffer size is constant and indicates the maximum amount of data (in bytes) that the user (i.e., SinkTester) is prepared to buffer.
    Calling the constructor is an implicit call to readyToAccept(aBufize).
  • Method void readyToAccept(n);
    Called by user to indicate that it is ready to accept "n" more bytes.
The user of SW_Sink (i.e., Class SinkTester) implements the following methods:
  • Method  void deliverData(byte data[]);
    SW_Sink calls this method to pass data to the user (presumably the data is then dropped from SW_Sink's receive buffer). Length of "data" (determined by data.length) has to be less than or equal to the number of bytes that the user is ready to accept.

Application Layer Service

Application layer consists of two classes SourceTester and SinkTester. SourceTester (SourceTester.java) sends a file to the SinkTester (SinkTester.java).  SinkTester flushes data every 64K and waits for 4 seconds where it cannot accept any data. SinkTester exits if no data is received for 120 seconds.

Testing and Debugging

In this assignment, programs run on different machines and each program may have multiple threads. The distributed property (or characteristic) of networking programs complicates testing and debugging.

A research method is devised to test distributed systems. According to this method, we specify the interactions between different entities of a distributed system in a file, called service file. In this assignment, eight different interaction types (figure 2) take place between the different entities: four on the source side, which are the constructor, sendData, closeSource and ackData; and four on the sink side, which are the constructor, readyToAccept, closeSink and deliverData. Those interactions are illustrated in Tester service class (Tester.java). The specifications of the interactions describe the relations between the eight interaction types. For example, the number of bytes delivered to Sink's user cannot increase the number of bytes sent by Source's user.  An interaction is of the following format:
 

void <method-name> (<parameters>){
   // print function name in log file
   if (condition) {
      // method body.
   } else
      throw new Error("<error message>");
}


After defining service methods, we need to correlate the network system (SourceTester, SW_Source, SinkTester and SW_Sink) to  Tester. Whenever a call is issued to an entity method, an RMI call is issued to the corresponding method in class Tester. For example, when SourceTester object calls SW_Source.sendData, SW_Source.sendData method issues an RMI call to Tester.sendData with the same parameters. Consequently, a developer can determine the correctness of both source and sink sides by checking that no errors were thrown during the execution of Tester. (This is not totally correct, because the network system can encounter a deadlock and yet no error has been thrown.  So, we add a condition: a file sent by Source has to be received)

Figure 2
Figure 2


At any single moment during the execution of the network system, there are many threads running on multiple machines. But in order to check the correctness of the network system against Tester, we need to ensure that, at any moment, a single thread in the network programs is running.

Class Tester provides a main lock which is used to synchronize among different programs and threads. When a thread locks the main lock, no other thread in the network system can lock the main lock, unless the lock is released. For example, when a thread in SW_Sink locks the main lock, SW_Source on a different machine cannot lock the main lock until SW_Sink releases the lock. (If there is no Tester, then each side (source or sink side) has its own lock).
 

  • Class Tester (Tester.java) provides the main lock with 4 methods:
    • Provides methods to lock and unlock the main lock:
      • "void lock();": locks the main lock.
      • "void unlock();": releases the main lock.
    • Provides methods to write to the log file:
      • "void print(String str);": writes string str to a log file named "List.log".
      • "void println(String str);": writes string str followed by '\n' to a log file named "List.log".
    • Specifies the data transfer service. It has two groups of methods: source group and sink group.
      • Source group has four methods:
        • void Source(int,String,int,int): called by the constructor of class SW_Source.
        • void sendData(byte[]): called by SW_Source.sendData method.
        • void closeSource(): called by SW_Source.closeSource method.
        • void ackData(int): called by SourceTester.ackData method.
      • Sink group has four methods:
        • void Sink(int,String,int,int): called by the constructor of class SW_Sink.
        • void readyToAccept(int): called by SW_Sink.readyToAccept method.
        • void closeSink(): called by SW_Sink.closeSink method.
        • void deliverData(byte[]): called by SinkTester.deliverData method.
Class Tester binds itself (using Naming.rebind method) to rmiregistry with name "Tester" and has the interface TesterInter ( TesterInter.java). Classes SourceTester and SinkTester do a lookup (using Naming.lookup method) for "Tester). Afterwards, the four classes SourceTester, SW_Source, SinkTester and SW_Sink can issue RMI calls to the methods exported by Tester.
It is worthy to mention again, that in order to issue an RMI call, the main lock has to be locked before the call is issued.

Figure 3 illustrates the direction of interactions between different entity of the network system (an arrow from entity A to entity B means that A calls a method at B, and if the arrow sinks into a small back circle, then this call is a remote call via the port name mentioned).

 
Figure 3
Figure 3


Assignment Files - added 3/21/05

  • Please copy hw5SourceFiles.zip. When you expand the files, you will find the following files:
    • Subdirectory "Source" has the following files:
      • SourceTester.java
      • SW_Source.java (a template is available in SW_Source.java).
      • NetworkSocket.java
      • TesterInter.java
    • Subdirectory "Sink" has the following files:
      • SinkTester.java
      • SW_Sink.java (a template is available in SW_Sink.java).
      • NetworkSocket.java
      • TesterInter.java
    • Subdirectory "Tester" has the following files:
      • Tester.java
      • TesterInter.java
      • RWLock.java (handles locking).
    • security policy file.
    • Simple HTTP class server.

How to start

  1. Implement "stop and wait" data transfer protocol.
    1. Transfer a very small file, 50 bytes.
    2. Transfer a file that is smaller than the send buffer in order to test method SW_Source.sendData.
    3. Transfer a file bigger than the buffer in order to test the correctness of your handling of the buffer (calling SourceTester.ackData).
  2. Increase the send window, but fix it to an arbitrary size. Then, handle sending and receiving of data and acknowledgments.
  3. Increase the loss probability (variable lossProb in NetworkSocket) at source side. Handle source resending accordingly.
  4. Increase the loss probability (variable lossProb in NetworkSocket) at sink side. Handle the acknowledgment loss accordingly.
  5. Increase the duplication probability (variable duplicateProb in NetworkSocket) at source side. Handle duplication at sink side.
  6. Increase the reorder probability (variable reorderProb in NetworkSocket) at source side. Handle reordering at sink side.
  7. Change the sending window from fixed window to adaptable window.
  8. Make random scenarios by changing loss, reorder and duplicate probability variables in NetworkSocket class.
This approach is not restrictive. You can do it in a different way.

Don't be tempted to code everything at once. 

Execution

  • Inside hw5_yourLastName/Tester directory
    • Compile files ("javac *.java").
    • Execute "rmic Tester".
  • Compile Source and Sink files.
  • Execute "rmiregistry &".
  • Run the tester and bind the server to "Tester":
    %java -Djava.rmi.server.codebase=file:///hw5_yourLastName/Tester/ -Djava.security.policy=../policy Tester
    You run the tester on a specific machine.  If you start rmiregistry at a different port (e.g., the default rmiport 1099 is used) by typing "rmiregistry <rmiport>", then you need to change the port of Tester.java to the correct one. The line to be changed can be found by searching "YRY".

    As an alternative,  you can also use the class-server (http server):
    - Run the class http server at <hostname>:
    %java examples.classServer.ClassFileServer <port> hw5_yourLastName/Tester/

    -Run the tester:
    %java -Djava.rmi.server.codebase=file:///<host name>:<port>/ -Djava.security.policy=../policy Tester

  • Run the sink:
    %java -Djava.security.policy=../policy SinkTester filename localPort SourceHostName SourcePortNo


    If your rmiregistry runs on a different machine, please adjust the lookup method parameter to "//<hostname>:<rmiregistryPort>/Tester". The line to be changed can be found by searching "YRY."
     
  • Run the source:
    %java -Djava.security.policy=../policy SourceTester filenameToBeSent localPort SinkHostName SinkPortNo StreamOption


    Similar to the sink, you may need to tell the source how to find RMI registry.

Design Specifications

Your design specification should demonstrate that you have thought about the problem and devised a plausible solution. Your solution should be described in prose, but please use diagrams or psuedo-code where appropriate. Clarity, concision and simplicity are virtuous; length is not.

Your design should also include a short description of how you will test your code to be sure it is correct. Test design is very challenging for network programs given its distributed nature. Be sure that you have designed tests that will accurately determine whether your code works correctly, and check for edge/boundary cases.

Your design specification should be submitted in hardcopy form as well as in online form by the deadline. We will try our best to provide feedback in a timely manner to you.

 

Useful Reading

(Ideas heavily and liberally borrowed from http://zoo.cs.yale.edu/classes/cs433/assignments/prog1/. Thanks to Prof. Richard Yang of Yale-CS and University of Maryland-CS.)

Any student may be asked to show and discuss his implementation in class, so be ready with your presentation.

Submit a zipped file of your source codes, scripts (to run your program) and report along with a hardcopy of your source codes, scripts, a couple of sample executions of your solution and report.

Use <hw#cs555_yourlastname_mmddyy.{zip,gz,ppt}> as the naming convention for your zipped or ppt files when emailing your submission to ajay.gupta@wmich.edu. Replace '#' with the appropriate homework number.

REMINDER: You are responsible for making yourself aware of and understanding the policies and procedures in the undergraduate (pp. 268-270) [Graduate (pp. 24-26)] Catalog that pertain to Academic Integrity. Additionally, easy availability of information, material, source codes, lecture notes etc on the Internet may make it possible to find solutions to your assignments on the Internet or elsewhere. It is okay to refer to those, understand them and use them to enhance your solutions, generate your own ideas etc. However, you must give proper and full credit to original authors of the work, if you include their ideas. Failing to do so is part of academic and professional dishonesty. It will not be tolerated in this class. Do not give in to temptations....

 

 

 

 


Home