Skip to content

Lab: GoBackN

March 26, 2013

#include “stdafx.h”
#include “RDT.h”
#include “StudentWork.h”

/********* STUDENTS WRITE THE NEXT SEVEN ROUTINES *********/

//chapter 3.4 pg 221

//global variables
int gBase;
int gNextSeqNum;
const int gN = 5; //this is the N in GoBackN in this case GoBack5

const int gSimMaxPkts = 100;//Maximum number of simulated packets
struct pkt gSendPkt[gSimMaxPkts];//Array for sending in order

const int gPayLoadSize = 20;//Maximum amout of information in checksum
const float gTimeOutSeconds = 20.0; //global for timeout in seconds

/* the following routine will be called once (only) before any other */
/* entity A routines are called. You can use it to do any initialization
Initialization routine*/
void A_init()
{
// This is the init routine for GoBackN pg 221 in text…
//Initialize global variables
gBase = 1;
gNextSeqNum = 1;
}

/* called from layer 5, passed the data to be sent to other side */
void A_output(struct msg message)
{
// A_output is really RDT send on pg 221
/*
p_code from eFSM on page 221 of text
if(nextSeqNum <(base+N){
…..
}
*/

if(gNextSeqNum < gBase+gN)
{
{//This is make packet on page 221 of the text
int checkSum = 0;//Inital Checksum =0
for (int i=0; i<gPayLoadSize; i++)//Send in incriments of 1 until payload is full
{
gSendPkt[gNextSeqNum].payload[i] = message.data[i];//sent packet with the first payload and first message segment ++
checkSum += message.data[i];//the checksum should be for the message data value
}
gSendPkt[gNextSeqNum].checksum = checkSum;//set to next checksum number for next packet
gSendPkt[gNextSeqNum].seqnum = gNextSeqNum;//get the next sequence number for the packet

}
//udt_send
tolayer3(A,gSendPkt[gNextSeqNum]);//send packet A to transport layer

if(gBase == gNextSeqNum)//Start the timeout timer after packet sent
//start time goes here
starttimer(A, gTimeOutSeconds);
gNextSeqNum++;
}
//else refuse on pg 221 is not implemented.
}

/* called from layer 3, when a packet arrives for layer 4 */
void A_input(struct pkt packet)
{
//check to see if pkt is not corrupt
int checkSum = 0;//set checksum to 0
for (int i=0; i<gPayLoadSize; i++)//add 1 to payload for each packet as it is sent
{
checkSum += packet.payload[i];//checksum should = the payload
}
if (checkSum != packet.checksum)//if the checksum is not equal to the packet checksum
{
printf(“\n Bad Checksum on Ack … Skipping\n”);//Drop the ack message and resend
return;
}
//if it is good, update base… pg 221
gBase = packet.acknum+1;
if(gBase ==gNextSeqNum)
stoptimer(A);//stop timer
else
starttimer(A, gTimeOutSeconds);//Start timer
}

/* called when A’s timer goes off */
void A_timerinterrupt()
{
//timeOut event on pg 221
starttimer(A, gTimeOutSeconds);
for (int i=gBase; i<gNextSeqNum; i++)//udt send
tolayer3(A,gSendPkt[i]);// resend packet

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//global variables that deal with part B
int gExpectedSequenceNumber;
struct pkt gAckPkt;

void B_output(struct msg message) /* need be completed only for extra credit */
{
}
/* Note that with simplex transfer from a-to-B, there is no B_output() */

/* called from layer 3, when a packet arrives for layer 4 at B*/
void B_input(struct pkt packet)
{
// corrupt or not expected got to do default…..
// check to see if packet not corrupt
int checkSum =0;
for(int i=0;i<gPayLoadSize;i++)
{
checkSum += packet.payload[i];
}
if (checkSum != packet.checksum) //If it is a bad checksum
{
tolayer3(B,gAckPkt);
printf(“\n Bad Checksum on Recrvr Packet, send Dup ACK…. skipping\n”);//State bad packet and send a duplicate ack asking for retransmit
return;
}
if (packet.seqnum != gExpectedSequenceNumber)//If the packet number is out of order
{
tolayer3(B,gAckPkt);
printf(“\n Not Expected send Dup Ack…. skipping\n”);//SState bad packet and send a duplicate ack asking for retransmit
return;
}

// not corrupt and expected
tolayer5(B,packet.payload);

gAckPkt.acknum =gExpectedSequenceNumber;//the ack message should include the corresponding sequence number
gAckPkt.payload[0] = ‘A’;gAckPkt.payload[1] = ‘C’;gAckPkt.payload[2] = ‘K’;//include in the ack message
gAckPkt.checksum = ‘A’+’C’+’K’;//include in the checksum

tolayer3(B,gAckPkt);
gExpectedSequenceNumber++;//up the expected sequence number for the next packet
}

/* called when B’s timer goes off */
void B_timerinterrupt()
{
}

/* the following rouytine will be called once (only) before any other */
/* entity B routines are called. You can use it to do any initialization */
void B_init()
{
gAckPkt.acknum = 0;//Ack Messages will a start at 0
gAckPkt.payload[0] = ‘A’; gAckPkt.payload[1] = ‘C’; gAckPkt.payload[2] = ‘K’;//What the AckPkts will contain
gAckPkt.checksum = ‘A’ + ‘C’ +’K’;//What checksum will include

int gExpectedSequenceNumber = 1;//Sequence of messages to start at 1
}

———————————————————————————————————————————————————————-

Lab Video:

Screen Shots:

Base Case: No Loss, No Corruption, 1 Packet Sent, Trace 5

RDT1

8 Packets Sent, No Loss, No Corruption, Trace 3

RDT2

8 Packets Sent, 50% Loss, No Corruption, Trace 3

RDT3

8 Packets Sent, No Loss, 50% Corruption, Trace 3

RDT4

8 packets sent, 50% Loss, 50% Corruption

RDT5[

From → Lab videos

Leave a Comment

Leave a comment