Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / multimedia / OpenGL

DataLink Simulator

4.88/5 (19 votes)
7 Feb 2010CPOL3 min read 97.4K   5.7K  
A C# simulation for DataLink layer using OpenGl
Source Code

Introduction

The Data Link Layer is Layer 2 of the seven-layer OSI model of computer networking. It corresponds to or is part of the link layer of the TCP/IP reference model.

Data Link Layer provides the functional and procedural means to transfer data between network entities and might provide the means to detect and possibly correct errors that may occur in the Physical Layer.

This C# simulation will cover data link layer’s flow control techniques which are:

  1. Stop and Wait
  2. Go Back N
  3. Selective Repeat

Stop and Wait

Stop-and-wait ARQ is the simplest kind of automatic repeat-request (ARQ) method. A stop-and-wait ARQ sender sends one frame at a time. After sending each frame, the sender doesn't send any further frames until it receives an ACK (acknowledgement) signal. After receiving a good frame, the receiver sends an ACK. If the ACK does not reach the sender before a certain time, known as the timeout, the sender sends the same frame again.

So now we have 3 scenarios:

  1. Frame reaches Receiver Rx, ack reaches Trasnmitter Tx.
  2. Frame times out.
  3. Frame reaches Receiver Rx, ack times out.

In the last case, the sender doesn't receive the ACK, times out, and sends the frame again. Now the receiver has two copies of the same frame, and doesn't know if the second one is a duplicate frame or the next frame of the sequence carrying identical data.

(For the sake of simplicity, if Rx already has the frame, the duplicate is ignored.)

stopWait.jpg

Using the Code

  • objselected_frame_stp_wt is the frame we selected from Transmitter listBox
  • dtimeout is our predetermined timeout
  • tsSend_Time is a timespan object calculated by a timer
  • objFrame and objAck are objects from class clssSqaure, responsible for creating and moving the primitives
C#
if (objselected_frame_stp_wt != null)
        {
            if (tsSend_Time.Seconds > dtimeout)//send time exceeded predetermined timeout
            {
                if (bsend_file) //Rx didn't receive Frame
                    lbl_receiver.Text = "Timeout";

                else            //Tx didn't receive Acknowledgment
                    lbl_sender.Text = "Timeout";

                timer1.Enabled = false;//stop sending
            }

            if (bsend_file)//Frame is being sent to Rx
            {
                if (LBx_Receiver.Items.Contains(objselected_frame_stp_wt))
                    lbl_sender.Text = "Resending " + objselected_frame_stp_wt.ToString();
                else
                    lbl_sender.Text = "Sending " + objselected_frame_stp_wt.ToString();

                if ((objFrame.Fxpos + dlen) > nwidth)//frame arrived to Rx
                {
                    if (!LBx_Receiver.Items.Contains(objselected_frame_stp_wt))
                    {
                        LBx_Receiver.Items.Add(objselected_frame_stp_wt);
                    }
                    lbl_sender.Text = "awaiting acknowledgement";
                    lbl_receiver.Text = "sending acknowledgement";
                    bsend_file = false;
                    dtstart = DateTime.Now;
                    objAck = new clssSqaure(nwidth, -20, -1, color_yellow);
                    lst_clssSqaure.Add(objAck);
                }
                objFrame.Fxpos += fspeed * objFrame.Fvec_X;
            }
            else//Ack is being sent to Tx
            {
                if (((objAck.Fxpos - dlen + 10) < (nwidth * -1)))//Ack arrived to Tx
                {
                    lbl_sender.Text = "Acknowledgement received";
                    if (LBx_Receiver.Items.Contains(objselected_frame_stp_wt))
                    {
                        LBx_Sender.Items.Remove(objselected_frame_stp_wt);
                    }
                    timer1.Enabled = false;
                    bsend_file = true;
                }
                objAck.Fxpos += fspeed * objAck.Fvec_X;
            }
        }        

Stop-and-wait ARQ is inefficient compared to other ARQs, because the time between packets - if the ACK and the data are received successfully- is twice the transit time.

To solve this problem, one can send more than one packet at a time with a larger sequence number and use one ACK for a set. This is what is done in Go-Back-N ARQ and the Selective Repeat ARQ.

Go-Back-N

The sending process continues to send a number of frames specified by a window size without receiving an ACK packet from the receiver.

If any frame was lost or damaged, or the ACK acknowledging them was lost or damaged, then that frame and all following frames in the window (even if they were received without error) will be re-sent.

Go_Back_N.png

Using the Code

SlidingWindow is a function used for both Go-Back-N and Selective Repeat.

Q_Frames is a Queue holding window size frames, when a frame reaches Rx successfully within time, an objAck is created and added to the Queue Q_Acks.

If a frame is dropped (and we are in the Go-Back-N mode), Rx will stop receiving.

C#
private void SlidingWindow(TimeSpan tsSend_Time, bool bIsGoBackN)
       {
           object[] arr_Frames = Q_Frames.ToArray();
           if (Q_Frames.Count != 0)//Sending Frames
           {
               objFrame.Fxpos += fspeed * objFrame.Fvec_X;
               lbl_sender.Text = "Sending " + arr_Frames[0].ToString();
               lbl_receiver.Text = "Receiving " + arr_Frames[0].ToString();

               if (objFrame.Fxpos + dlen > nwidth)//frame reached Rx
               {
                   object Objreceivedframe = Q_Frames.Dequeue();
                   if (tsSend_Time.Seconds < dtimeout) //within time
                   {
                       if (bcontinue_receive)//sending was not interrupted,
                   //receive frames normally
                       {
                           LBx_Receiver.Items.Add(Objreceivedframe);
                           LBx_Log.Items.Add(Objreceivedframe.ToString() + " received");
                           Q_Acks.Enqueue(Objreceivedframe);

                           objAck = new clssSqaure(nwidth, -20, -1,
                       color_yellow);//Send Ack
                           lst_clssSqaure.Add(objAck);
                       }
                   }
                   else//frame exceeded time
                   {
                       LBx_Log.Items.Add(Objreceivedframe.ToString() + " timed out");
                       if (bIsGoBackN && bcontinue_receive)
                       {
                           LBx_Log.Items.Add("Rx stopped receiving");
                           bcontinue_receive = false;//stop receiving
                       }
                   }
                   dtstart = DateTime.Now; //reset time
                   objFrame.Fxpos = 10 - nwidth; //reset Frame position
               }

           }
           if (Q_Acks.Count != 0)//Sending Ack
           {
               objAck.Fxpos += fspeed * 2 * objAck.Fvec_X;
               if (((objAck.Fxpos - dlen + 10) < (nwidth * -1)))//Ack arrived to Tx
               {
                   LBx_Log.Items.Add("Ack received");
                   LBx_Sender.Items.Remove(Q_Acks.Dequeue());
                   lst_clssSqaure.Remove(objAck);
               }
           }
           if (Q_Frames.Count == 0 && Q_Acks.Count == 0)
           {
               lbl_receiver.Text = lbl_sender.Text = "Ready";
               lbl_TimeElapsed.Text = string.Empty;
           }
       }

Selective Repeat

The sending process continues to send a number of frames specified by a window size even after a frame loss.

Unlike Go-Back-N ARQ, the receiving process will continue to accept and acknowledge frames sent after an initial error. If a frame from the sender does not reach the receiver, the sender continues to send subsequent frames until it has emptied its window.

The receiver continues to fill its receiving window with the subsequent frames, replying each time with an ACK containing the sequence number of the earliest missing frame. Once the sender has sent all the frames in its window, it re-sends the frame number given by the ACKs, and then continues where it left off.

Selective_Repeat.png

History

  • 7th February, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)