Beruflich Dokumente
Kultur Dokumente
Written by:
Daim Abbas Kazmi
Afrasiab Khan
Project:
User Datagram Protocol is a transportation layer protocol and is used to exchange large files
over the Internet at fast speeds such as sound transmission or video transmission. However, it
does not ensure reliable transfer but provides Best Effort Delivery as a network layer
protocol.
It is less reliable than Transmission Control Protocol TCP because there is no committed
connection and confirmations of received packets are not generally given to the sending side
and lost parcels are not re-sent i.e. retransmission. This reduces its reliability. A client can
send a document to a UDP server. Server receives and can process the document. Before the
customer sends record / message to read it, the server must be running.
In order to make UDP increasingly solid, we need to add a few features to it with the ultimate
goal that when a packet is lost it can retransmit that packet also receive packet
acknowledgments. We also need to reorder the packets on the receiver side and handle the
received duplicate packets. These features will increase the reliability of the protocol but may
reduce the speed of the protocol.
RUNTIME
When the program starts client-side makes a UDP socket with the already running server side
using its IP address. An array of 5 packts (special structure that contains buffer, sequence
number and acknowledgement number) is initialized. The file to be sent is opened. Elements
0-4 of array are given the sequence numbers from 1-5.
After this, 492 bytes of data is read into each of the elements from the file. After this the data
is sent one by one using the socket to the server side. After the five packets sent, the timer is
started. On the server-side array of same window size is initialized and the receiving packets
are stored in similar manner into this array named packt_recev []. On receiving each packet,
the receiver side will send an ack. The ack would be the sequence number. An array of
window size is initialized only to check for received acks. This array is initialized by zeros
and the index equaling received ack number is converted to one.
Timeout is checked after each receiving acknowledgement. If the time becomes more than
timeout i.e. 0.001 seconds in our case. All the packts having sequence number same to those
index having zeros are resend and timer is reset. The ‘while’ loop will not break until all the
acks are received. After this the client side, again read the next bytes of data into array of
packts. The sequence number remains same.
After receiving all five packets, the array of received packts are sorted by using sequence
number so the data is in order. After that the data is written such that only the data part of the
packt is written into the file. Array of size is used for this purpose. A ‘for’ loop is used to
write the ordered data into the file.
At end of file, the client sends a zero sized packet. Receiver on receiving this identify that
whole file has reached. At this point both sides would close their sockets and the files. Also,
some info is shown on terminals of both sides, like total packets sent and received, windows
exchanged and total bytes transaction.
CODE
Receiver Side
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#define window 5
#define MAXLINE 492
struct packt{
unsigned int seqnumber;
unsigned int acknumber;
char buff[MAXLINE];
};
FILE *file;
struct packt packt_recv[window];
if (argc != 3)
{
printf("Error usage : %s <port_serv> <File_name>\n",argv[0]);
return EXIT_FAILURE;
}
int n;
int size;
int total = 0;
int try = 0;
int i=0;
int eof = 0;
int t_bytes=0;
int n_window=0;
int packt_size[window];
if (n==0)
{ printf("FIN received \n" );
eof = 1;
break;
}
}
packt_size[packt_recv[i].seqnumber-1]=n;
//sending acknowledgements
printf("Sending ack\n");
sendto(sockfd,&packt_send.acknumber, 4, 0, (struct sockaddr *) &servaddr, len);
total++;
}
n_window++;
//reordering
qsort(&packt_recv[0],i,sizeof(struct packt),compar);
}
printf("Total bytes recieved: %d\n",t_bytes );
printf("Total packets: %d\n",total );
printf("Total windows: %d\n",n_window );
printf("Success");
fclose(file);
close(sockfd);
return 0;
}
Sender Side
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>
struct packt
{
unsigned int seqnumber;
unsigned int acknumber;
char buff[MAXLINE];
};
FILE *file;
struct sockaddr_in servaddr;
struct packt packt_send[window];
//Timeout handling
if (dif>0.001)
{
printf("Error at acknowledgment: Timeout \n");
for (int i=0;i<n;i++)
{
if (ack[i]!=1)
{
printf("Timed out packet in window: %d \n",i+1);
//Retransmission of lost Packet
sendto(sfd,&packt_send[i],sizeof(packt_send),0,(struct sockaddr*)&servaddr,len);
printf("Resending data: %d \n",i+1);
}
}
//Resetting timer
start=clock()/CLOCKS_PER_SEC;
}
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&packt_send, 0, sizeof(struct packt)*window);
int n;
int len = sizeof(servaddr);
int nread;
clock_t start;
int eof = 0;
int k;
int t_bytes=0;
int n_windows=0;
int total=0;
file = fopen(argv[3],"rb");
if(file == NULL)
{
printf("Error Opening the file\n");
return 0;
}
int count = 0;
//initializing data
for(int j=0;j<window;j++)
{
//Reading data from file into buffers
nread = fread(packt_send[j].buff , 1, MAXLINE, file);
int size = (void*)&packt_send[j].buff[nread] - (void*)&packt_send[j];
//Sending packets
t_bytes=t_bytes+size;
k=sendto(sockfd, &packt_send[j], size, 0, (struct sockaddr *) &servaddr, len);
printf("Sequence Number: %d Size:%d \n",packt_send[j].seqnumber,size );
count++;
total++;
//If whole file is sent and its time to send FIN
if(nread < MAXLINE)
{
if(feof(file))
{
eof = 1;
break;
}
}
if(ferror(file))
{
printf("Error Reading\n");
}
}
n_windows++;
//Starting timer as last packet is sent
start=clock()/CLOCKS_PER_SEC;
//Function call
receiveacks(sockfd,start,count);
}
//Sending FIN
printf("FIN sent.\n");
sendto(sockfd, NULL, 0,0, (const struct sockaddr *) &servaddr, sizeof(servaddr));