
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h>


#define INT_DIGITOS 63
int act=0;
long int bytes=0;
int Tbytes=0;
float T;
struct sockaddr_in name;
/* definicion de las estructuras para el timer*/
struct itimerval contador; 
/* Valor inicial del contador */
struct timeval tiempoInicial;
/* Tiempo de repetici�n del contador */
struct timeval tiempoRepeticion;

/*strings que seran impresos en el terminal*/ 
char tx[3]="Tx=";
char n[6]=" Kb/s\n";


long int size=0;

/* las siguientes funciones son para convertir de un long a ASCII e int a ASCII*/
static char buf[INT_DIGITOS + 2];
/* Buffer para INT_DIGITS dígitos, signo - y fin de string '\0' */
char * ltoa(long int i, unsigned int base)
{
 char *p = buf + INT_DIGITOS + 1;                   /* apunta a posición de unidades */
  int dig, signo=0;
  if (i<0) {signo=1;i = -i;}
  if(base<=0 || base>36) base=10;          /*evita división por cero */
  do { dig=(i%base); if (dig <=9) *--p = '0' + dig; else *--p= '7'+ dig ; i /= base;}
  while (i != 0);
  if(signo) *--p = '-';
  return p;
}

char * itoa(float i, unsigned int base)
{
          return (ltoa((long int)i, base));
}

/****************************************************************************/

/*la funcion sig_alrm que se activa segun <base tiempo> imprime la velocidad de transmision*/

static void sig_alrm(int signo) 
{	
if (act!=0){
write(1,tx,3);
write(1,itoa((float)bytes/T,10),sizeof(itoa((float)bytes/T,10))+1);
write(1,n,6);
bytes=0;
if(Tbytes>=size)act=0;
}
return;	
}
///////////////////////////MAIN//////////////////////////////////
int
main(int argc, char * argv[])
{
   char buf[1024];
   int s, n, ns, len;
    int i;
   size = atoi(argv[2]);
       if (argc != 4)
     {
	printf("Error en argumentos! \n");
	printf("Sintaxis: tt_server <port> <size> <base_tiempo> \n");
	exit(-1);
     }


	/* Se rellena el tiempo inicial del contador con segun en argumento de entrada */
	tiempoInicial.tv_sec=atoi(argv[3])/1000;
	tiempoInicial.tv_usec=atoi(argv[3])%1000*1000;

	/* Se rellena el tiempo de repetici�n */
	tiempoRepeticion.tv_sec=atoi(argv[3])/1000;
	tiempoRepeticion.tv_usec=atoi(argv[3])%1000*1000;

      
	/* Se rellenan los datos del contador */
	contador.it_value=tiempoInicial;
	contador.it_interval=tiempoRepeticion;
	
	

    T= (float)atoi(argv[3])/1000;

  
     /* Crea el socket. */
    s = socket(AF_INET, SOCK_STREAM, 0);

    /* Crea la direccion del server. */
    name.sin_family = AF_INET;
    name.sin_port = htons(atoi(argv[1]));
    name.sin_addr.s_addr = htonl(INADDR_ANY); /* Use the wildcard address.*/
    len = sizeof(struct sockaddr_in);
   
     /*Rellena el buf con basura*/
    for (i=0; i<1024;i++) buf[i]='a';
    printf("\n Inicio Traffic test server\n");
    
     /* Bind el socket a la direccion. */
    if( bind(s, (struct sockaddr *) &name, len))
		printf("bind error");

    /* Se escuchan conexiones */
    listen(s, 5);

    /* aceptamos conexion.  */
    ns = accept(s, (struct sockaddr *) &name, &len);

    printf("Connection from : %s\n",inet_ntoa(name.sin_addr));
    
     /*duerme por 5 segundos antes de empezar las transmisiones*/
 
    sleep(5);
      
     /* Se cambia el tratamiento de la se�al por defecto para que llame a
	 * nuestra funci�n sig_alrm */
      signal (SIGALRM, sig_alrm);
     /*Inicio del timer*/
     setitimer (ITIMER_REAL, &contador, NULL);
    /*este pause se desbloquera con la primera señal de sigalrm*/ 
     pause();

     /*comienza la transmision de <size (argv[2])> bits*/

    while (Tbytes < atoi(argv[2])){
    act=1;
     bytes++;
     Tbytes++;
     if (send(ns, buf, sizeof(buf), 0) < 0) {
            perror("send");
            exit(1);
        }
    }
    /*una vez terminado manda un string que marca el fin de la transmision*/
    if (send(ns, "fin", 3, 0) < 0) {
            perror("send");
            exit(1);}
    /*se desactiva el timer*/ 
        tiempoRepeticion.tv_sec=0;
	tiempoRepeticion.tv_usec=0;

    /*se espera por la recepcion de los datos, aunque no se aga nada con ellos*/

    while ((n = recv(ns, buf, sizeof(buf), 0)) > 0);
    /*se cierran los sockets y se finaliza el programa*/
    close(ns);
    close(s);
    exit(0);
}
