Wednesday, 3 April 2019

An C program to implement Echo_Client and Echo_server using TCP to estimate the round trip time from client to the server.

Round-Trip Time
Request Response Behavior
Round trip time(RTT) is the length of time it takes for a signal to be sent plus the length of time it takes for an acknowledgement of that signal to be received. This time therefore consists of the propagation times between the two point of signal.

On the Internet, an end user can determine the RTT to and from an IP(Internet Protocol) address by pinging that address. The result depends on various factors :-
  • The data rate transfer of the source’s internet connection.
  • The nature of transmission medium.
  • The physical distance between source and destination.
  • The number of nodes between source and destination.
  • The amount of traffic on the LAN(Local Area Network) to which end user is connected.
  • The number of other requests being handled by intermediate nodes and the remote server.
  • The speed with which intermediate node and the remote server function.
Let us assume one sender and one receiver.
Sender is the one who want to calculate the mean Round Trip Delay for the connection between sender and receiver. So sender sends a hundred (100) packets, sized 1byte each (a char in C programming Language), and wait to get it back from the receiver.Both sender and receiver uses the command socket() to open a socket for the communication. Receiver uses connect() with arguments a struct sockaddr_in to connect to the sender. Sender uses bind() to give the sockfd the local address so that it can then call accept and connect to the receiver. After bind() the sender calls accept() which block until somebody connects (call connect()) to the socket.When connection is established sender send 100 packets , every one is 1byte (char tosend) and receives another one back. Double t1 sume the start times (before send()) and double t2 sums the end times(after recv()). When all 100 packets are sent RTT is calculated by (t2-t1)/100




At sender Side:

#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>

#define MYPORT 3490
#define SIZE_TO_SEND 1000
#define MY_IP "127.0.0.1"

int main(int argc, char *argv[]) {
 int sockfd,sockfd2;
 char tosend = 's'; //a char (1byte) to send to receivers
 char ack;
 struct sockaddr_in my_addr,rcvr_addr;
 struct timeval start,end;
 int sin_size = sizeof(my_addr),i,k,num_packet_sent,optval;
 double t1,t2;

 //open TCP socket,bind and accept RECEIVERS connections
 if( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) ==-1){
  perror("socket error");
  exit(1);
 }
 my_addr.sin_family = AF_INET;
 my_addr.sin_port = htons(MYPORT);
 my_addr.sin_addr.s_addr = inet_addr(MY_IP);
 memset(my_addr.sin_zero, '\0', sizeof(my_addr.sin_zero));
 //allow reuse of port
 optval = 1;
 if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int)) == -1) {
  perror("setsockopt");
  exit(1);
 }
 //bind(socketfd, struct about my address,sizeofmy address);
 if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) {
  perror("bind");
  exit(1);
 }
 listen(sockfd,10);

 sockfd2 = accept(sockfd, (struct sockaddr *)&rcvr_addr, &sin_size);

 //connections OK
 //send 100 packet of size 1 byte and for each send wait for ack
 t1=0.0; t2=0.0;
 printf("Sending 100 messages 1 byte each and wait for ack.\n");
 for(num_packet_sent=0;num_packet_sent<100;num_packet_sent++){
  if(gettimeofday(&start,NULL)) {
   printf("time failed\n");
   exit(1);
  }
  send(sockfd2,&tosend,sizeof(char),0);
  optval=recv(sockfd2,&ack,sizeof(char),0);
  if(optval==-1) {
   perror("Receive error");
   exit(1);
  }
  else{
   if(gettimeofday(&end,NULL)) {
    printf("time failed\n");
    exit(1);
   }
             t1+=start.tv_sec+(start.tv_usec/1000000.0);
             t2+=end.tv_sec+(end.tv_usec/1000000.0);
  }
 }
 //calculate and print mean rtt
 printf("RTT = %g ms\n",(t2-t1)/100);
 printf("close sockets and exit\n");
 shutdown(sockfd2,2);
 shutdown(sockfd,2);
 exit(0);
}


At Receiver Side 

#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>

#define SENDER_PORT 3490
#define SENDER_IP "127.0.0.1"

int main(int argc, char *argv[]) {

 int sockfd;
 int rcv_num,loop_count,i;
 char buf;
 struct sockaddr_in sender_addr;

 //open socket and connect
 if( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) ==-1){
  perror("socket error"); // do some error checking!
  exit(1);
 }

 sender_addr.sin_family = AF_INET;
 sender_addr.sin_port = htons(SENDER_PORT);
 sender_addr.sin_addr.s_addr = inet_addr(SENDER_IP);
 memset(sender_addr.sin_zero, '\0', sizeof(sender_addr.sin_zero));

 if ((connect(sockfd,(struct sockaddr *)&sender_addr,sizeof(sender_addr))) ==-1){
  perror("connect error"); // do some error checking!
  exit(1);
 }

 //connection established
 printf("Connection to sender established\n");
 //reads 100 packets of 1 byte and sends them back as ack packets
 printf("Receive 100 packets of 1 byte and send then back\n");
 for(i=0;i<100;i++){
  rcv_num = recv(sockfd,&buf,sizeof(char),0);
  if(rcv_num!=0) {
   //send  ack
   send(sockfd,&buf,sizeof(char),0);
  }
  else{
   perror("Receive error");
   exit(1);
  }
 }
 printf("\tDone\nClose socket and exit\n");
 close(sockfd);
 exit(0);
}


Compilation & Run –
Server side:
gcc serverrtt.c -o serverrtt
./server

Client side:
gcc clientrtt.c -o clientrtt
./client
Output 

At Receiver Terminal 

Connection to sender established
Receive 100 packets of 1 byte and send then back
        Done
Close socket and exit

At Server 

Sending 100 messages 1 byte each and wait for ack.
RTT = 2.65503e-05 ms
close sockets and exit

1 comment: