Skip to content
Snippets Groups Projects
Clients.cpp 6.7 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 = 30;


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])
		else
			if (array[i] == delimiter[pos])

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);
Leonardo's avatar
Leonardo committed
	   printf("Intentando conexion con %s:%d ...\n",HOST,TCP_PORT);

Leonardo's avatar
Leonardo committed
	   if (connect(client_socket, res->ai_addr, res->ai_addrlen)<0){
		   printf("Error, imposible establecer conexion con el servidor.\n");
		   return;
	   }
	   //primitiva SEND
	   char *msg = "TCP";
	   int msg_size = strlen(msg);
	   int sent_msg_size = send(client_socket, msg, msg_size, 0);
Leonardo's avatar
Leonardo committed
		   printf("Error, imposible establecer conexion con el servidor.\n");
Leonardo's avatar
Leonardo committed
	   printf("Conexion establecida.\n");

	   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.
	   int received_data_size = 1;
	   while(received_data_size > 0)
	   {
		   int data_size = MAXLEN;
		   received_data_size = recv(client_socket, buf, data_size, 0);
		   fin = printFrame( received_data_size, recibido, fin, buf);
	   }
	   close(client_socket);
	   freeaddrinfo(res);
int printFrame(int received_data_size, char* recibido, int fin, char* buf){
	   double fpms = 1000/30; //frames for ms
	   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 += 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);
		   imshow("cliente", frame);
		   waitKey(fpms);
	       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 -= inicio;
	   }
	   return fin;
}

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
Leonardo's avatar
Leonardo committed
	   printf("Enviando Suscripcion a %s:%d ...\n", HOSTNAME, UDP_PORT);::fflush(stdout);
	   if (sendDatagramUDPtoHostname(sock, HOSTNAME, buffer, UDP_PORT) < 0)
		   error("Error on send first datagram");

	   // ESPERO RESPUESTA DEL SERVIDOR
Leonardo's avatar
Leonardo committed
	   struct timeval timeout;
	   timeout.tv_sec = 5;
	   timeout.tv_usec = 0;
	   setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

	   bzero(buffer,256);
	   struct sockaddr_in from;
Leonardo's avatar
Leonardo committed
	   if (recvfrom(sock,buffer,256,0,(struct sockaddr *)&from, &length) < 0){
		   if ((errno == EAGAIN) || (errno == EWOULDBLOCK)){
			   printf("Error, no hay respuesta del servidor.\n");
			   return;
		   }else{
			   printf("Error al recibir datos.\n");
			   return;
		   }
	   }else
		   printf("Listo");
	   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 );
	   char* frameBuffer = new char[100];

	   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.
	   int received_data_size = 1;

Leonardo's avatar
Leonardo committed
	   while(true)
		   received_data_size = recvfrom( sock , buf , MAXLEN , 0 , (struct sockaddr *)&from , &length );
Leonardo's avatar
Leonardo committed
		   if (received_data_size < 1){
			   if ((received_data_size < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))){
		   			printf("Error, no hay respuesta del servidor.\n");
		   			return;
			   }else{
		   			printf("Error al recibir datos.\n");
		   			return;
			   }
		   }else
			   fin = printFrame( received_data_size, recibido, fin, buf);

	   //while (true)
	   //{
		//   memset ( frameBuffer , '\0' , 100 );
		//   if ( recvfrom( sock , frameBuffer , 100 , 0 , (struct sockaddr *)&from , &length ) < 0)
		//	  error("recv from UDP frames");
		//   printf("%s\n", frameBuffer);
	   //}




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);
	}
}