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:
- Stop and Wait
- Go Back N
- 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:
- Frame reaches Receiver Rx, ack reaches Trasnmitter Tx.
- Frame times out.
- 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.)
Using the Code
objselected_frame_stp_wt
is the frame we selected from Transmitter listBox
dtimeout
is our predetermined timeouttsSend_Time
is a timespan object calculated by a timerobjFrame
and objAck
are objects from class clssSqaure
, responsible for creating and moving the primitives
if (objselected_frame_stp_wt != null)
{
if (tsSend_Time.Seconds > dtimeout)
{
if (bsend_file)
lbl_receiver.Text = "Timeout";
else
lbl_sender.Text = "Timeout";
timer1.Enabled = false;
}
if (bsend_file)
{
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)
{
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
{
if (((objAck.Fxpos - dlen + 10) < (nwidth * -1)))
{
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.
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.
private void SlidingWindow(TimeSpan tsSend_Time, bool bIsGoBackN)
{
object[] arr_Frames = Q_Frames.ToArray();
if (Q_Frames.Count != 0)
{
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)
{
object Objreceivedframe = Q_Frames.Dequeue();
if (tsSend_Time.Seconds < dtimeout)
{
if (bcontinue_receive)
{
LBx_Receiver.Items.Add(Objreceivedframe);
LBx_Log.Items.Add(Objreceivedframe.ToString() + " received");
Q_Acks.Enqueue(Objreceivedframe);
objAck = new clssSqaure(nwidth, -20, -1,
color_yellow);
lst_clssSqaure.Add(objAck);
}
}
else
{
LBx_Log.Items.Add(Objreceivedframe.ToString() + " timed out");
if (bIsGoBackN && bcontinue_receive)
{
LBx_Log.Items.Add("Rx stopped receiving");
bcontinue_receive = false;
}
}
dtstart = DateTime.Now;
objFrame.Fxpos = 10 - nwidth;
}
}
if (Q_Acks.Count != 0)
{
objAck.Fxpos += fspeed * 2 * objAck.Fvec_X;
if (((objAck.Fxpos - dlen + 10) < (nwidth * -1)))
{
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.
History
- 7th February, 2010: Initial post