CSF303 Lab5
CSF303 Lab5
CSF303 Lab5
The behavior of rdt 2.5 sender and receiver is captured in the FSM shown in Fig. 1 (a) and Fig. 1 (b)
respectively.
Page 1 of 8
Fig. 1 (b) rdt 2.5 receiver FSM
Page 2 of 8
rdt 2.5 client (sender) implementation (udp_client.c)
Note: This is partial implementation of rdt 2.5 sender with no packet loss assumption. This code
file is provided separately named as udp_client.c
/*
Simple udp client with stop and wait functionality
*/
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];
DATA_PKT send_pkt,rcv_ack;
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
int state = 0;
while(1)
{
switch(state)
Page 3 of 8
{ case 0: printf("Enter message 0: ");//wait for sending packet with
seq. no. 0
fgets(send_pkt.data,sizeof(send_pkt),stdin);
send_pkt.sq_no = 0;
if (sendto(s, &send_pkt, sizeof(send_pkt), 0 , (struct
sockaddr *) &si_other, slen)==-1)
{
die("sendto()");
}
state = 1;
break;
case 2:
printf("Enter message 1: ");
//wait for sending packet with seq. no. 1
fgets(send_pkt.data,sizeof(send_pkt),stdin);
send_pkt.sq_no = 1;
if (sendto(s, &send_pkt, sizeof(send_pkt) , 0 , (struct
sockaddr *) &si_other, slen)==-1)
{
die("sendto()");
}
state = 3;
break;
case 3:
//waiting for ACK 1
if(recvfrom(s, &rcv_ack, sizeof(rcv_ack), 0, (struct sockaddr
*) &si_other, &slen) == -1)
{
die("recvfrom()");
}
if (rcv_ack.sq_no==1)
{ printf("Received ack seq. no. %d\n",rcv_ack.sq_no);
state = 0;
break;
}
}
}
close(s);
return 0;
}
Page 4 of 8
rdt 2.5 Receiver (Server) Implementation (udp_server.c)
Note: This is partial implementation of rdt 2.5 server with no packet loss assumption. This code
file is provided separately named as udp_server.c
int main(void)
{
struct sockaddr_in si_me, si_other;
int s, i, slen = sizeof(si_other) , recv_len;
//char buf[BUFLEN];
DATA_PKT rcv_pkt;
ACK_PKT ack_pkt;
//create a UDP socket
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
// zero out the structure
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
Page 5 of 8
//bind socket to port
if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
{
die("bind");
}
int state =0;
while(1)
{
switch(state)
{ case 0:
{ printf("Waiting for packet 0 from sender...\n");
fflush(stdout);
Page 6 of 8
}
}
}
close(s);
return 0;
}
Exercise-1:
a) Compile and execute udp_client.c and udp_server.c programs separately and verify/understand the
protocol behavior in no loss condition.
Fig. 3 (a) rdt 2.5 data packet loss scenario Fig. 3 (b) rdt 2.5 ACK packet loss scenario
Page 7 of 8
Exercise-2:
a) Extend the given client (udp_client.c) and server (udp_server.c) programs to handle data packet and ACK
packet loss.
Therefore to test the working of packet loss functionality for rdt 2.5 we need to introduce fake packet loss
in our program. Let’s think, how to do it….?????
Hint: Modify your receiver program such that when it receives a data packet through a recvfrom() system
call it discards packet randomly (even it is with correct expected sequence number). In this manner some
of the data packets are discarded. So for such packets receiver will not create and send ACK packet as per
protocol semantics. This leads to timeout at sender.
You can use rand() function to randomly set a flag and based on that discard or receive a packet.
Timer Implementation:
Sender initiate a timer after sending a packet. If corresponding ACK packet is not received at sender (either
data packet or ACK lost) before timer expires then it retransmits that packet and start times. Otherwise, it
stops the timer and sends the packet with next sequence number.
The recvfrom() system call is a blocking call. So we have to make it non-blocking call. If recvfrom() call
does not receive any data within a specified time (timeout value) then it should unblock.
Alternative Approach
Timer setting using function alarm(unsigned int seconds) just after the sendto() system call is required.
*******
Page 8 of 8