Homework 5 - Data Link Protocol Implementation

Document last modified: 


Protocols Overview Several data link layer protocol examples are given in the Tanenbaum text. The network and physical layer operations used by the data link layer in Tanenbaum have been implemented in Java using the User Datagram Protocol of the Internet protocol set. The Java implementation is very similar to that given in the text on page 202 for C. Essentially, the network and physical layer protocols have been implemented. Based upon those functions, it is possible to implement data link protocols 1 through 4 on a single or multiple workstations running Java.


Protocol Discussion

The Java implementation follows that of the text as closely as reasonably possible, remembering that Java is object-oriented and the text example is not. The Java definitions that correspond to that of page 202 follow:
 

public class Protocol {
        public final static int frame_arrival = 0;
        public final static int chksum_err = 1;
        public final static int timeout = 2;

        public static void to_network_layer(String s);
        public static String from_network_layer();
}

public class Frame {
        public String info;
        public int seq;
        public int ack;

        Frame(int socket);
        public String from_physical_layer();
        public void to_physical_layer(String remoteAddress, int remotePort);
        public int wait_for_event();
        public void start_timer(int k);
        public void stop_timer(int k);
}

Differences between Java and Text Implementation

Note that only the functionality needed for Protocols 1-4 has been implemented in the two following Java classes.

  1. Protocol
  2. Frame
    1. Frame(int port); - Creates a new Frame given a port number.
    2. public String from_physical_layer( ); - Returns the message data load as a String from the physical layer, and the fields of the frame object (seq, ack, and info) are initialized.
    3. public void to_physical_layer(String remoteAddress, int remotePort); - Sends a Frame through the physical layer to the host at remoteAddress and port number remotePort.
    4. public int wait_for_event( ); - Wait for an event and return the event number, one of either frame_arrival, chksum_err, or timeout.
    5. public void start_timer(int k); - Start timer number k.
    6. public void stop_timer(int k); - Stop timer number k.

Assignment

  1. Verify protocol 3 operation (given below) and implement protocols 1, 2, and 4 from the text to further your understanding of each. Note that the Protocol from_network_layer and to_network_layer functions do not issue prompts in case you're using this protocol interactively.
  2. When running the protocols on one host, the to_physical_layer parameter for remoteAddress will be "localhost". The sender and receiver must send to the other's ports.

  3. If the receiver listens for frames to arrive on port 888, the sender must transmit to port 888. In sender3 of protocol 3, the following instruction defines the local port that will be used to send and receive frames:

     

        Frame s = new Frame(777);

    The program instruction:

     

         s.to_physical_layer("localhost", 888);

    actually sends the frame s to, in this case on the same host localhost and the receiver3 port 888.

    Note that protocol 4 is symmetric, having only one program that both sends and receives. Since two programs cannot share the same port on the same machine, two versions of protocol 4 are needed when run on one host. Name one protocol4A and the other protocol4B and use two different ports in the Frame( port) constructor in each version. Note that this is not necessary when running on two different host machines, both machines can use the same ports.

  4. Run protocols 1, 2, 4 on two different hosts, sending on one and receiving on the other. You will need to determine the IP of each machine by entering arp -a at a DOS window (or by entering ipconfig /all for W2K) on each which should display the machine's IP in a format similar to Interface: 149.160.29.93, then edit the IP into the to_physical_layer parameter for remoteAddress of each program. In Protocol 3 below, the change would be:
  5.  

         s.to_physical_layer("149.160.29.93", 888);

    Alternatively make two separate directories with complete copies of files and change one protocol copy to use different send and receive ports as was done in protocol 3.

  6. Modify the timeout parameter in the Constants.java file for protocol 4 until timeouts occur.

     

    You may need to insert an:

    if (event != frame_arrival) System.out.println("timeout"); 

    in protocol 4 to notify you that a timeout actually occurred.

  7. Modify the Constants.java file to vary the size of the data buffers.  The buffersize determines the number of bytes sent to the physical layer and received from the physical layer. Run for protocols 1, 2, 4 for a large and small data buffer size. Note that both hosts should use the same size buffers or truncation will occur.
  8. Modify the Constants.java file to vary the number of frames lost.  Run for protocols 1, 2, 4 for a large and small number of lost frames.

     


Turn In

  1. Cover sheet with your name, date, Homework 5. Please staple all pages together.
  2. Listing of each sender/receiver file for protocol 1, 2, and 4 (protocol 4 needs only one).
  3. Observations of running protocols on single or multiple machines. Discuss differences and give supporting outputs or other evidence.
  4. Observations on modifying timeout parameter in file Constants.java on appropriate protocols. Use at least three different timeouts from 10 ms. to 5000 ms. Discuss differences, if any, witnessed for each protocol tested and whether the behavior was as expected for each protocol. Give supporting outputs or other evidence.
  5. Observations on modifying buffersize parameters in file Constants.java and sending a large file for protocols 1, 2, 4. Use at least three different sizes from 1 to 2000. Discuss differences witnessed for each and give supporting outputs or other evidence. Note that the testdata file can be sent by:
  6. Observations on modifying lostframes parameter in file Constants.java and sending a file for protocols 1, 2, 4. Use at least three different numbers from 0 to 20. Discuss differences witnessed for each protocol and give supporting outputs or other evidence. Note that the testdata file can be sent by:
  7. The testdata is a large file filled with sequential digits 0..9 to more easily recognize when a protocol failure occurs.
  8. The protocols are designed for two communicating hosts. Consider whether any (or all) of the protocols could be spoofed by a third sender. Try one and discuss the results and give supporting outputs or other evidence. Remember that the ports of all senders and receivers must be unique on the same machine by changing the following:
Frame s = new Frame(777);

Hints


Example - Protocol 3

Protocol 3 from Tanenbaum is implemented below as an example using the Java network and data link definitions. Note that one weakness of all the protocols is that the network layer is expected to always have data available. Consult the text and notes for details of Protocol 3.

Use

del *.class

Sender3 and Receiver3 - Changeable parameters:

public class sender3 extends Protocol {
    public static void main(String args[]) throws Exception
    {  int next_frame_to_send;
        Frame r = new Frame(777);
        Frame s = new Frame(666);
        String buffer;
        int event;

        next_frame_to_send = 0;
        buffer = from_network_layer();
        while (true)
        {       s.info = buffer;
                 s.seq = next_frame_to_send;
                 s.to_physical_layer("localhost", 888);
                 r.start_timer(s.seq);
                 event = r.wait_for_event();
                 if (event == frame_arrival)
                {   r.from_physical_layer();
                     if (r.ack == next_frame_to_send)
                    {   buffer = from_network_layer();
                         next_frame_to_send =
                                   (next_frame_to_send + 1) % 2;
                     }
                }
        }
    }
}

public class receiver3 extends Protocol {
    public static void main(String args[]) throws Exception
   {   int frame_expected;
        Frame r = new Frame(888);
        Frame s = new Frame(999); 
        int event;

        frame_expected = 0;
        while (true)
        {   event = r.wait_for_event();
             if (event == frame_arrival)
            {   r.from_physical_layer();
                 if (r.seq == frame_expected)
                {   to_network_layer(r.info);
                     Frame_expected = (frame_expected + 1) % 2;
                }
                s.ack = 1 - frame_expected;
                s.to_physical_layer("localhost", 777);
             }
         }
    }
}
 
 
 

 


Java Listing of Data Link Layer Implementation

The following four class definitions, Constants, Protocol, Frame, and DataGram, implement the functionality described by the text. Only Constants will need to be modified.

Constants.java - Defines three constants.

public class Constants {
        public static final int buffersize = 13;
        public static final int lostframes = 0;
        public static final int timeout = 1000;
}

Protocol.java - Serves to define events and network functions. When implementing a protocol, one must inherit Protocol to have access to these definitions, for example: public class sender3 extends Protocol.
 

public class Protocol {
        public final static int frame_arrival = 0;
        public final static int chksum_err = 1;
        public final static int timeout = 2;

        public static void to_network_layer(String s)
        {       System.out.print(s);
        }

        public static String from_network_layer()
        {      byte buffer[] = new byte[Constants.buffersize];
                try { System.in.read(buffer); }
                catch (Exception e) {};
                String s = new String(buffer,0);
                return s;
        }
}

Frame.java - Frame is actually the majority of the Data Link layer, providing  access to the physical layer. One key difference between the text and Java implementation is the requirement that Frame's be created for a port number on the host for sending and receiving and a time limit for waiting a Frame arrival. Note that the port can only be in use by one Frame. Another point of difference is the need to address the Frame to a specific destination host and port on the destination.
 

public class Frame {
        public String info;
        public int seq=0;
        public int ack=0;

        private boolean timer = false;
        private int timelimit=Constants.timeout;
        private DataGram datagram;
        private int lostframes=0;

        Frame(int port)
        {       datagram = new DataGram(port);
        }

        public String from_physical_layer()
        {       String s = datagram.receive();

                int index;
                index = s.indexOf(" ");
                seq = (new Integer(s.substring(0,index))).intValue();
                s = s.substring(index+1);
                index = s.indexOf(" ");
                ack = (new Integer(s.substring(0,index))).intValue();
                info = s.substring(index+1);
                return info;
        } 

  public void to_physical_layer(
      String remoteAddress, int remotePort)
  {       datagram.send(remoteAddress, remotePort,
                 "" + seq + " " + ack + " " + info);
   }

   public int wait_for_event()
   {  int timelimit = 0;
       if(timer) timelimit = this.timelimit;
       try { datagram.start_receive(timelimit); }
       catch(Exception e) { return Protocol.timeout; }
       if(Constants.lostframes > 0 && 
               ++lostframes % Constants.lostframes == 0)
              return Protocol.timeout;
        return Protocol.frame_arrival;
  }

  public void start_timer(int k)
  {  timer = true;
   }

   public void stop_timer(int k)
   {   timer = false;
    }
}

 

DataGram.java - Used by Frame to access the physical layer for sending and receiving. Implemented using User Datagram Protocol. Whenever a datagram containing a Frame is to be received, a thread is started that waits for its arrival. If a timer runs out while waiting for arrival, the thread is stopped, terminating the wait for arrival.
 

// Low-level User Datagram class to send/receive datagram.

import java.net.*;

public class DataGram {
   private byte buffer[]=new byte[Constants.buffersize+4];
   private int remotePort;              // Allow for 1 digit Ack and Seq
   private String remoteAddress;
   private DatagramSocket ds = null;
   private String info;

   DataGram(int localPort)
   {       try { ds = new DatagramSocket(localPort);}
            catch (Exception e) {System.out.println("Exception " + e
                                                         + " port " + localPort ); }
    }

    public void send(String remoteAddress, int remotePort, String s) 
    {   byte buffer[]=new byte[s.length()];
         s.getBytes(0, s.length(), buffer, 0);
         try { ds.send(new DatagramPacket(buffer, s.length(),
                InetAddress.getByName(remoteAddress), remotePort));
         }
         catch (Exception e) { System.out.println("Exception " + e); };
   }

 public void start_receive(int timeout) 
                   throws Exception
 { ds.setSoTimeout(timeout);
    info = "";
    DatagramPacket p = 
          new DatagramPacket(buffer, buffer.length);
    ds.receive(p); 
    info = new String(p.getData(), 0, 0, p.getLength());
 } 

 public String receive() 
 {       return info;
  }

 
 
 
 
 
 
 
 
 
 

 


Java Development Kit

Java requires Win95, NT, W2K, Unix, or other multitasking operating system.



 Document last modified: