#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> #include <opencv2/opencv.hpp> using namespace cv; 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]) 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); printf("Intentando conexion con %s:%d ...\n",HOST,TCP_PORT); //primitiva CONNECT 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); if (sent_msg_size == -1) { printf("Error, imposible establecer conexion con el servidor.\n"); return; } 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 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 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; 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; while(true) { received_data_size = recvfrom( sock , buf , MAXLEN , 0 , (struct sockaddr *)&from , &length ); 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); //} 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); } }