From 0009aa269a43cad4cc6f47adfa34e16f9712264e Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Thu, 6 Apr 2017 17:41:34 +0200 Subject: [PATCH] [Done] UDP communication thread first step --- .vscode/settings.json | 10 ++ central-manager/central-manager.c | 119 ++++++++++++----- central-manager/lib/network/udp/server.c | 6 +- central-manager/lib/network/udp/server.h | 1 + global/plane.c | 156 ----------------------- global/plane.h | 18 --- 6 files changed, 100 insertions(+), 210 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 global/plane.c delete mode 100644 global/plane.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4e46053 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "files.associations": { + "*.ipp": "cpp", + "array": "cpp", + "slist": "cpp", + "initializer_list": "cpp", + "utility": "cpp", + "functional": "cpp" + } +} \ No newline at end of file diff --git a/central-manager/central-manager.c b/central-manager/central-manager.c index d58ec37..9d66d47 100644 --- a/central-manager/central-manager.c +++ b/central-manager/central-manager.c @@ -19,11 +19,11 @@ int main(int argc, char* argv[]){ =========================================================*/ /* (1) Ecoute TCP */ pthread_create(&listenManagers[0], NULL, LISTEN_TCP, NULL); - if( DEBUGMOD&THR ) printf("LISTEN THREAD[TCP] démarré\n"); + if( DEBUGMOD&THR ) printf("[main][TCP_LISTEN_THREAD] démarré\n"); /* (2) Ecoute UDP */ pthread_create(&listenManagers[1], NULL, LISTEN_UDP, NULL); - if( DEBUGMOD&THR ) printf("LISTEN THREAD[UDP] démarré\n"); + if( DEBUGMOD&THR ) printf("[main][UDP_LISTEN_THREAD] démarré\n"); /* [2] On attends la fin de tous les THREADS @@ -33,7 +33,7 @@ int main(int argc, char* argv[]){ /* [3] On ferme la SOCKET d'écoute globale ==========================================================*/ - printf("FERMETURE DE TOUTES LES CONNECTIONS!\n"); + printf("[main] FERMETURE DE TOUTES LES CONNECTIONS!\n"); } @@ -77,7 +77,7 @@ void* LISTEN_TCP(){ } - printf("\tTCP Listen Port: %d\n", TCP_PORT); + printf("[main][TCP_LISTEN_THREAD] Listen Port: %d\n", TCP_PORT); @@ -94,7 +94,7 @@ void* LISTEN_TCP(){ /* 3. Si erreur, on attend une nouvelle connection */ if( CLIENT_SOCKET < 0 ){ - if( DEBUGMOD&SCK ) printf("\tErreur connection TCP\n"); + if( DEBUGMOD&SCK ) printf("[main][TCP_LISTEN_THREAD] Erreur connection\n"); break; } @@ -108,13 +108,13 @@ void* LISTEN_TCP(){ /* 5. On lance un thread pour le traitement de ce client */ pthread_create(&TCPManagers[index], NULL, managePlane, (void*)(intptr_t) CLIENT_SOCKET); - if( DEBUGMOD&THR ) printf("\tTHREAD[TCP][%d] démarré\n", index); + if( DEBUGMOD&THR ) printf("[main][TCP_LISTEN_THREAD][COM_THREAD][%d] démarré\n", index); /* 6. On signale que ce "manager" est maintenant actif */ activeTCPManagers[index] = 1; }else - if( DEBUGMOD&THR ) printf("\tAucun thread TCP libre!\n"); + if( DEBUGMOD&THR ) printf("[main][TCP_LISTEN_THREAD] Aucun thread libre!\n"); } @@ -126,7 +126,7 @@ void* LISTEN_TCP(){ /* [4] On ferme la SOCKET d'écoute globale ==========================================================*/ - printf("FERMETURE DE L'ECOUTE TCP!\n"); + printf("[main][TCP_LISTEN_THREAD] FERMETURE DE L'ECOUTE TCP!\n"); close(LISTENSOCK); return NULL; @@ -154,6 +154,7 @@ void* LISTEN_UDP(){ /* [0] Initialisation des variables ==========================================================*/ int CLIENT_SOCKET; // contiendra la socket UDP à envoyer sur un THREAD + struct sockaddr_in serverInfo; // contiendra les infos serveur struct sockaddr_in clientInfo; // contiendra les infos client char client_ip[20]; // IP du client socklen_t len; // taille de la socket @@ -169,16 +170,16 @@ void* LISTEN_UDP(){ ==========================================================*/ if( DROP_UDP_SERVER(UDP_PORT, &SOCKET) < 0 ){ - if( DEBUGMOD&SCK ) printf("\tErreur de mise en place de la socket UDP\n"); + if( DEBUGMOD&SCK ) printf("[main][UDP_LISTEN_THREAD] Erreur de mise en place de la socket d'écoute\n"); // On ferme la SOCKET d'écoute globale - printf("\tFERMETURE DE LA SOCKET UDP!\n"); + printf("[main][UDP_LISTEN_THREAD] FERMETURE DE LA SOCKET D'ECOUTE UDP!\n"); close(SOCKET); return NULL; } - printf("\tUDP Listen Port: %d\n", UDP_PORT); + printf("[main][UDP_LISTEN_THREAD] Listen Port: %d\n", UDP_PORT); @@ -194,20 +195,67 @@ void* LISTEN_UDP(){ read = recvfrom(SOCKET, buffer, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len); /* 2. Si erreur reception ou taille incorrecte */ - if( read != sizeof(struct bind_header) ){ - if( DEBUGMOD&BUF ) printf("\t\t[UDP] READ('%s') = %d bytes (expected: %d)\n", buffer, read, (int) sizeof(struct bind_header)); - break; + if( read != sizeof(char)+sizeof(unsigned short) ){ + if( DEBUGMOD&BUF ) printf("[main][UDP_LISTEN_THREAD] read('%s') = %d bytes (expected: %d)\n", buffer, read, (int) (sizeof(char)+sizeof(unsigned short)) ); + continue; } /* 3. On récupère l'adresse IP du client */ inet_ntop(AF_INET, &(clientInfo.sin_addr), client_ip, 20); - if( DEBUGMOD&SCK ) printf("\t[UDP] %s connecté\n", client_ip); + if( DEBUGMOD&SCK ) printf("[main][UDP_LISTEN_THREAD] '%s' connecté\n", client_ip); - /* 3. On parse la requête*/ + /* 4. On parse la requête*/ memcpy(&request, buffer, sizeof(struct bind_header)); - printf("\t\t\t[UDP] parsed:\n\t\t\t\tflag = %d\n\t\t\t\tport = %d\n", (int) request.flags, request.port); + printf("[main][UDP_LISTEN_THREAD] received: {flag = %d; port = %d}\n", (int) request.flags, request.port); + + /* 5 Si on veut un port de communicatin */ + if( request.flags&BINDHEAD_PRT ){ + + /* 5.1 On bind une socket sur un port random */ + if( DROP_UDP_SERVER(0, &CLIENT_SOCKET) < 0 ){ + + if( DEBUGMOD&SCK ) printf("[main][UDP_LISTEN_THREAD] Erreur de création de la socket COM\n"); + + // On ferme la SOCKET CLIENT + close(CLIENT_SOCKET); + + // On retire le flags PORT pour dire qu'on a pas pu ouvrir une socket de comm. + request.flags -= BINDHEAD_PRT; + } + + } + + /* 5.2 Si on veut on port de communication */ + if( request.flags&BINDHEAD_PRT ){ + + /* On récupère le port de la socket de communication */ + len = sizeof(struct sockaddr_in); + if( getsockname(CLIENT_SOCKET, (struct sockaddr*) &serverInfo, &len) < 0 ){ + + if( DEBUGMOD&SCK ) printf("[main][UDP_LISTEN_THREAD] Erreur de recherche du port COM ouvert\n"); + + close(CLIENT_SOCKET); + + // On retire le flags PORT pour dire qu'on a pas pu ouvrir une socket de comm. + request.flags -= BINDHEAD_PRT; + + // Si on a le port -> on le met dans la reponse + }else + request.port = serverInfo.sin_port; + + } + + if( DEBUGMOD&SCK ) printf("[main][UDP_LISTEN_THREAD] { port: %d }\n", serverInfo.sin_port); + + /* 8. On envoie la réponse */ + memcpy(buffer, &request, sizeof(struct bind_header)); + if( send(SOCKET, buffer, strlen(buffer), 0) < 0 ){ + printf("[main][UDP_LISTEN_THREAD] Impossible de répondre au client!\n"); + continue; + } + @@ -222,13 +270,13 @@ void* LISTEN_UDP(){ /* 5. On lance un thread pour le traitement de ce client */ pthread_create(&UDPManagers[index], NULL, manageTerminal, (void*)(intptr_t) CLIENT_SOCKET); - if( DEBUGMOD&THR ) printf("\tTHREAD[UDP][%d] démarré\n", index); + if( DEBUGMOD&THR ) printf("[main][UDP_LISTEN_THREAD][COM_THREAD][%d] démarré\n", index); /* 6. On signale que ce "manager" est maintenant actif */ activeUDPManagers[index] = 1; }else - if( DEBUGMOD&THR ) printf("\tAucun thread UDP libre!\n"); + if( DEBUGMOD&THR ) printf("[main][UDP_LISTEN_THREAD] Aucun thread UDP libre!\n"); } @@ -236,7 +284,7 @@ void* LISTEN_UDP(){ /* [n] On ferme la SOCKET d'écoute globale ==========================================================*/ - printf("\tFERMETURE DE LA SOCKET UDP!\n"); + printf("[main][UDP_LISTEN_THREAD] FERMETURE DE LA SOCKET UDP!\n"); close(SOCKET); return NULL; @@ -285,14 +333,14 @@ void* managePlane(void* THREADABLE_SOCKET){ /* 2. Si erreur reception */ if( read < 0 ){ - if( DEBUGMOD&BUF ) printf("\t\t[TCP] READ = %d\n", read); + if( DEBUGMOD&BUF ) printf("[main][TCP_LISTEN_THREAD][COM_THREAD] READ = %d\n", read); break; } /* 3. On désérialise la requête*/ - printf("\t\tPLANE Request(%d bytes) : '%s'\n", read, request); + printf("[main][TCP_LISTEN_THREAD][COM_THREAD] PLANE Request(%d bytes) : '%s'\n", read, request); /* [3] Gestion de la requête =========================================================*/ @@ -313,7 +361,7 @@ void* managePlane(void* THREADABLE_SOCKET){ activeTCPManagers[index] = 0; /* 3. On arrête le THREAD */ - if( DEBUGMOD&THR ) printf("\t\tTHREAD[TCP][%d] libéré\n", index); + if( DEBUGMOD&THR ) printf("[main][UDP_LISTEN_THREAD][COM_THREAD][%d] libéré\n", index); pthread_exit(NULL); } @@ -347,32 +395,37 @@ void* manageTerminal(void* THREADABLE_SOCKET){ int read; // compteur struct sockaddr_in clientInfo; socklen_t len; - int TCP_SOCKET = (intptr_t) THREADABLE_SOCKET; // Socket client + int UDP_SOCKET = (intptr_t) THREADABLE_SOCKET; // Socket client char request[MAX_BUF_LEN]; // Requête // char response[MAX_BUF_LEN]; // Réponse do{ + printf("[main][UDP_LISTEN_THREAD][COM_THREAD] waiting for terminal request\n"); /* [2] Récupération de la requête =========================================================*/ /* 1. On lit sur la socket */ - read = recvfrom(TCP_SOCKET, request, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len); + len = sizeof(struct sockaddr_in); + read = recvfrom(UDP_SOCKET, request, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len); /* 2. Si erreur reception */ - if( read < 0 ){ - if( DEBUGMOD&BUF ) printf("\t\t[TCP] READ = %d\n", read); - break; - } + if( DEBUGMOD&BUF ) printf("[main][UDP_LISTEN_THREAD][COM_THREAD] READ = %d\n", read); + + if( read < 0 ) + continue; /* 3. On désérialise la requête*/ - - - printf("\t\tPLANE Request(%d bytes) : '%s'\n", read, request); + printf("[main][UDP_LISTEN_THREAD][COM_THREAD] TERMINAL Request(%d bytes) : '%s'\n", read, request); /* [3] Gestion de la requête =========================================================*/ + /* [4] Envoi reponse + =========================================================*/ + strcpy(request+strlen(request), "-bla\0"); + send(UDP_SOCKET, request, strlen(request), 0); + }while( 0 ); @@ -388,6 +441,6 @@ void* manageTerminal(void* THREADABLE_SOCKET){ activeTCPManagers[index] = 0; /* 3. On arrête le THREAD */ - if( DEBUGMOD&THR ) printf("\t\tTHREAD[TCP][%d] libéré\n", index); + if( DEBUGMOD&THR ) printf("[main][UDP_LISTEN_THREAD][COM_THREAD][%d] libéré\n", index); pthread_exit(NULL); } diff --git a/central-manager/lib/network/udp/server.c b/central-manager/lib/network/udp/server.c index ca529f0..0677e28 100644 --- a/central-manager/lib/network/udp/server.c +++ b/central-manager/lib/network/udp/server.c @@ -12,8 +12,8 @@ int DROP_UDP_SERVER(const int pPort, int* pListenSock){ /* [0] Initialisation des variables =========================================================*/ // CREATION - static struct sockaddr_in addr; // contiendra les infos du serveur - int STATUS; // status + struct sockaddr_in addr; + int STATUS; // status // INITIALISATION *pListenSock = -1; @@ -42,7 +42,7 @@ int DROP_UDP_SERVER(const int pPort, int* pListenSock){ /* [3] On publie la SOCKET =======================================================*/ - STATUS = bind(*pListenSock, (struct sockaddr*) &addr, sizeof(addr)); + STATUS = bind(*pListenSock, (struct sockaddr*) &addr, sizeof(struct sockaddr_in)); if( DEBUGMOD&SCK ) printf("\t\tUDP BIND = %d\n", STATUS); diff --git a/central-manager/lib/network/udp/server.h b/central-manager/lib/network/udp/server.h index 5470bce..7ff77ce 100644 --- a/central-manager/lib/network/udp/server.h +++ b/central-manager/lib/network/udp/server.h @@ -13,6 +13,7 @@ * * ==OUT== * @pListenSocket Pointeur sur le à remplir => contiendra un pointeur sur la socket d'écoute + * @pAddr Pointeur sur le à remplir => contiendra un pointeur sur les infos server * * ==RETURN== * @status -1 si erreur, sinon 0 diff --git a/global/plane.c b/global/plane.c deleted file mode 100644 index 376a8ee..0000000 --- a/global/plane.c +++ /dev/null @@ -1,156 +0,0 @@ -#include - -#include "avion.h" - -// caractéristiques du déplacement de l'avion -struct deplacement dep; - -// coordonnées spatiales de l'avion -struct coordonnees coord; - -// numéro de vol de l'avion : code sur 5 caractères -char numero_vol[6]; - -/******************************** - *** 3 fonctions à implémenter - ********************************/ - -int ouvrir_communication(){ - // fonction à implémenter qui permet d'entrer en communication via TCP - // avec le gestionnaire de vols - return 1; -} - -void fermer_communication(){ - // fonction à implémenter qui permet de fermer la communication - // avec le gestionnaire de vols -} - -void envoyer_caracteristiques(){ - // fonction à implémenter qui envoie l'ensemble des caractéristiques - // courantes de l'avion au gestionnaire de vols -} - -/******************************** - *** Fonctions gérant le déplacement de l'avion : ne pas modifier - ********************************/ - -// initialise aléatoirement les paramètres initiaux de l'avion -void initialiser_avion(){ - // initialisation aléatoire du compteur aléatoire - int seed; - time(&seed); - srandom(seed); - - // intialisation des paramètres de l'avion - coord.x = 1000 + random() % 1000; - coord.y = 1000 + random() % 1000; - coord.z = 900 + random() % 100; - - dep.cap = random() % 360; - dep.vitesse = 600 + random() % 200; - - // initialisation du numero de l'avion : chaine de 5 caractères - // formée de 2 lettres puis 3 chiffres - numero_vol[0] = (random() % 26) + 'A'; - numero_vol[1] = (random() % 26) + 'A'; - sprintf (&numero_vol[2], "%03d", (random() % 999) + 1); - numero_vol[5] = 0; -} - -// modifie la valeur de l'avion avec la valeur passée en paramètre -void changer_vitesse(int vitesse){ - if (vitesse < 0) - dep.vitesse = 0; - else if (vitesse > VITMAX) - dep.vitesse = VITMAX; - else dep.vitesse = vitesse; -} - -// modifie le cap de l'avion avec la valeur passée en paramètre -void changer_cap(int cap){ - if ((cap >= 0) && (cap < 360)) - dep.cap = cap; -} - -// modifie l'z de l'avion avec la valeur passée en paramètre -void changer_z(int alt){ - if (alt < 0) - coord.z = 0; - else if (alt > ALTMAX) - coord.z = ALTMAX; - else coord.z = alt; -} - -// affiche les caractéristiques courantes de l'avion -void afficher_donnees(){ - printf("Avion %s -> localisation : (%d,%d), z : %d, vitesse : %d, cap : %d\n", - numero_vol, coord.x, coord.y, coord.z, dep.vitesse, dep.cap); -} - -// recalcule la localisation de l'avion en fonction de sa vitesse et de son cap -void calcul_deplacement(){ - float cosinus, sinus; - float dep_x, dep_y; - int nb; - - if (dep.vitesse < VITMIN){ - printf("Vitesse trop faible : crash de l'avion\n"); - fermer_communication(); - exit(2); - } - if (coord.z == 0){ - printf("L'avion s'est ecrase au sol\n"); - fermer_communication(); - exit(3); - } - - cosinus = cos(dep.cap * 2 * M_PI / 360); - sinus = sin(dep.cap * 2 * M_PI / 360); - - dep_x = cos(dep.cap * 2 * M_PI / 360) * dep.vitesse * 10 / VITMIN; - dep_y = sin(dep.cap * 2 * M_PI / 360) * dep.vitesse * 10 / VITMIN; - - // on se déplace d'au moins une case quels que soient le cap et la vitesse - // sauf si cap est un des angles droit - if ((dep_x > 0) && (dep_x < 1)) dep_x = 1; - if ((dep_x < 0) && (dep_x > -1)) dep_x = -1; - - if ((dep_y > 0) && (dep_y < 1)) dep_y = 1; - if ((dep_y < 0) && (dep_y > -1)) dep_y = -1; - - //printf(" x : %f y : %f\n", dep_x, dep_y); - - coord.x = coord.x + (int)dep_x; - coord.y = coord.y + (int)dep_y; - - afficher_donnees(); -} - -// fonction principale : gère l'exécution de l'avion au fil du temps -void se_deplacer() -{ - while(1) - { - sleep(PAUSE); - calcul_deplacement(); - envoyer_caracteristiques(); - } -} - -int main() -{ - // on initialise l'avion - initialiser_avion(); - - afficher_donnees(); - // on quitte si on arrive à pas contacter le gestionnaire de vols - if (!ouvrir_communication()) - { - printf("Impossible de contacter le gestionnaire de vols\n"); - exit(1); - } - - // on se déplace une fois toutes les initialisations faites - se_deplacer(); -} diff --git a/global/plane.h b/global/plane.h deleted file mode 100644 index fab4475..0000000 --- a/global/plane.h +++ /dev/null @@ -1,18 +0,0 @@ -#define ALTMAX 20000 -#define ALTMIN 0 - -#define VITMAX 1000 -#define VITMIN 200 - -#define PAUSE 2 - -struct coord { - int x; - int y; - int z; -}; - -struct deplacement { - int cap; - int vitesse; -}; \ No newline at end of file