Skip to content
Snippets Groups Projects
Clients.cpp 5.42 KiB
Newer Older
#include "Clients.h"
#include "Util.h"
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
const char delimiter[] = "Grupo25";
const int keepAliveIntervalSeconds = 5;


typedef struct keepAliveData{
	int keepAliveId;
	int socketId;
	char* ip;
};



void* keepAliveMethod(void* ptr);

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#define MAXLEN 1048576 //1024*1024


/**
 * Funcion auxiliar que retorna dentro del array indicando la posicion del comienzo del delimitador
 * array: arreglo a consultar
 * len: largo de array
 * delimiter: delimitador a buscar
 * inicio: desde que posicion arrancar a buscar
 */
int findPosDelimiter(const char *array, int len, int inicio) {
	int i = -1;
	int pos = 0;
	for (i = inicio; i<len; i++) {
		if (sizeof(delimiter)-1 == pos) {
			if (array[i] == delimiter[pos]) {
				return i - sizeof(delimiter) + 2;
			} else {
				pos=0;
			}
		} else {
			if (array[i] == delimiter[pos]) {
				pos++;
			} else {
				pos=0;
			}
		}
	}
	return -1;
}

void TCP(const char* HOST){
	   int client_socket = socket(AF_INET, SOCK_STREAM, 0);

	   //obtenemos la direccion con getaddrinfo
	   struct addrinfo hints, *res;
	   memset(&hints, 0, sizeof hints);
	   hints.ai_family = AF_INET;
	   hints.ai_socktype = SOCK_STREAM;
	   getaddrinfo(HOST, STR(TCP_PORT), &hints, &res);

	   //primitiva CONNECT
	   connect(client_socket, res->ai_addr, res->ai_addrlen);

	   printf("Intentando conexion con %s:%d\n",HOST,TCP_PORT);

	   //primitiva SEND
	   char *msg = "TCP";
	   int msg_size = strlen(msg);
	   int sent_msg_size = send(client_socket, msg, msg_size, 0);
	   if (sent_msg_size == -1) {
		   printf("ERROR: imposible establecer conexion con el servidor");
		   return;
	   }

	   printf("Conexion establecida con %s:%d\n",HOST,TCP_PORT);

	   char buf[MAXLEN]; // se almacenan los datos TCP recibidos en cada recv
	   char recibido[MAXLEN]; // mantiene el historico de datos recibidos, quitando los frames ya dibujados
	   int fin = 0; // Mantiene el indice del array recibido.

	   double fpms = 1000/30; //frames for ms

	   int received_data_size = 1;
	   while(received_data_size > 0)
	   {
		   //primitiva RECEIVE
		   int data_size = MAXLEN;

		   received_data_size = recv(client_socket, buf, data_size, 0);

		   printf("Datos recibidos: %d\n", received_data_size);

		   // en el arrray 'recibido' se mantiene los datos que ya exisitian mas los nuevos.
		   for(int j = 0; j < received_data_size; j++) {
			   recibido[fin+j] = buf[j];
		   }
		   fin = fin + received_data_size;
		   int inicio = 0;
		   int found = -1;
		   while ((found = findPosDelimiter(recibido, fin+1, inicio)) != -1) {
			   char jpg[found-inicio];
			   for (int h = 0; h < found-inicio; h++) {
				   jpg[h] = recibido[inicio+h];
			   }
			   printf("Nuevo jpeg size: %li\n", sizeof(jpg));
			   	   	       namedWindow("cliente", CV_WINDOW_AUTOSIZE);
			   	   	       Mat rawData = Mat(1, found, CV_8UC1, jpg);
			   	   	       Mat frame = imdecode(rawData, CV_LOAD_IMAGE_COLOR);

	   	       inicio = found + sizeof(delimiter)-1;
		   }

		   if (inicio != 0) {
			   // mueve los datos recibidos al inicio, quitando el (o los) frame dibujado y el delimitador
			   for (int d = inicio; d < fin+1; d++) {
				   recibido[d-inicio] = recibido[d];
			   }
			   fin = fin-inicio;
		   }
}

void UDP(char* HOSTNAME){


	   unsigned int length;
	   struct from;

	   // CREATE SOCKET
	   int sock = socket(AF_INET, SOCK_DGRAM, 0);
	   if (sock < 0) error("error when creating socket");

	   char buffer[256];
	   bzero(buffer,256);
	   sprintf(buffer, "subscription");

	   // ENVIO PEDIDO DE SUSCRIPCION
	   printf("Sending Subscription\n");
	   if (sendDatagramUDPtoHostname(sock, HOSTNAME, buffer, UDP_PORT) < 0)
		   error("Error on send first datagram");

	   // ESPERO RESPUESTA DEL SERVIDOR
	   bzero(buffer,256);
	   struct sockaddr_in from;
	   if (recvfrom(sock,buffer,256,0,(struct sockaddr *)&from, &length) < 0)
		   error("recvfrom");
	   printf("Subscription: %s\n", buffer);

	   char* keepAliveId = new char[3];
	   keepAliveId[0] = buffer[9];
	   keepAliveId[1] = buffer[10];
	   keepAliveId[2] = '\0';

	   printf("keepAliveId is : %s\n", keepAliveId);

	   keepAliveData* kaData = new (keepAliveData);
	   kaData->keepAliveId = atoi(keepAliveId);
	   kaData->socketId = sock;
	   kaData->ip = new char[strlen(HOSTNAME)+1];
	   sprintf(kaData->ip, "%s" , HOSTNAME);
	   (kaData->ip)[strlen(HOSTNAME)] = '\0';

		pthread_t* hilos = new pthread_t[1];
	    pthread_create ( &hilos[0], NULL, keepAliveMethod, (void *)kaData);


	   while (true)
	   {
		   bzero(buffer,256);
		   if (recvfrom(sock,buffer,256,0,(struct sockaddr *)&from, &length) < 0)
			  error("recv from UDP frames");
		   printf("%s\n", buffer);
	   }


	   close(sock);
}


void* keepAliveMethod(void* ptr){
	keepAliveData* kaData = (keepAliveData*)ptr;
	char* buffer = new char[13];
	sprintf(buffer, "KEEPALIVE:%d", kaData->keepAliveId);
	buffer[13] = '\0';
	while (1){
		sleep(keepAliveIntervalSeconds);
		printf("Sending keep alive request :%d\n", kaData->keepAliveId );
		sendDatagramUDPtoHostname(kaData->socketId, kaData->ip, buffer, UDP_PORT);
	}
}