Lib tcp/udp in progress

This commit is contained in:
xdrm-brackets 2017-04-01 17:01:36 +02:00
parent b41a8d304f
commit 94c4769241
22 changed files with 869 additions and 588 deletions

1
central-manager/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vscode

29
central-manager/Makefile Normal file
View File

@ -0,0 +1,29 @@
CFLAGS=-Wall -pthread
# Runs 'all' depenency as default / i.e. 'make' command will run 'make all' implicitly
default: all
lib/network/tcp/server.o: lib/header.h lib/network/tcp/server.h lib/network/tcp/server.c
gcc $(CFLAGS) -c -o lib/network/tcp/server.o lib/network/tcp/server.c
lib/network/udp/server.o: lib/header.h lib/network/udp/server.h lib/network/udp/server.c
gcc $(CFLAGS) -c -o lib/network/udp/server.o lib/network/udp/server.c
lib/util.o: lib/util.h lib/util.c
gcc $(CFLAGS) -c -o lib/util.o lib/util.c
# Compiles the SGCA
boot: lib/network/tcp/server.o lib/network/udp/server.o lib/util.o central-manager.h central-manager.c
gcc $(CFLAGS) -o boot lib/network/udp/server.o lib/network/tcp/server.o lib/util.o central-manager.c
# Run full compilation
all: boot
# cleans the compiled files
clean:
rm boot;
rm ./**/*.o

View File

@ -1,85 +1,218 @@
#include "central-manager.h"
/*
*
* @argv : {0:program name}
*
* @history
* [0] Initialisation des variables
* [1] On démarre le SERVEUR d'écoute globale
* [2] Attente d'une demande de connection, puis création d'un THREAD
* [1] On démarre le SERVEUR TCP d'écoute globale
* [2] On démarre le SERVEUR UDP d'écoute globale
* repeat:
* [3] Attente d'une demande de connection TCP -> création d'un THREAD
* [4] Attente d'une demande de connection UDP -> création d'un THREAD
* si SIGINT:
* [3] On attends la fin de tous les THREADS
* [4] On ferme la SOCKET d'écoute globale
*
*/
int main(int argc, char* argv[]){
/* [1] Lancement des THREADS d'écoute
=========================================================*/
/* (1) Ecoute TCP */
pthread_create(&listenManagers[0], NULL, LISTEN_TCP, NULL);
if( DEBUGMOD&THR ) printf("LISTEN THREAD[TCP] démarré\n");
/* (2) Ecoute UDP */
pthread_create(&listenManagers[1], NULL, LISTEN_UDP, NULL);
if( DEBUGMOD&THR ) printf("LISTEN THREAD[UDP] démarré\n");
/* [2] On attends la fin de tous les THREADS
==========================================================*/
pthread_join(listenManagers[0], NULL);
pthread_join(listenManagers[1], NULL);
/* [4] On ferme la SOCKET d'écoute globale
==========================================================*/
printf("FERMETURE DE TOUTES LES CONNECTIONS!\n");
}
/* Attente de connection TCP
*
* @history
* [0] Initialisation des variables
* [1] On démarre le SERVEUR TCP d'écoute globale
* [2] Attente d'une demande de connection TCP -> création d'un THREAD
* [3] On attends la fin de tous les THREADS
* [4] On ferme la SOCKET d'écoute TCP globale
*
*/
void* LISTEN_TCP(){
/* [0] Initialisation des variables
==========================================================*/
int THREADABLE_SOCKET = -1; // contiendra le BUS DE COMMANDE utilisateur à envoyer à un THREAD
struct sockaddr_storage clientInfo; // contiendra les infos client
char repeat; // sert à sortir de la boucle
socklen_t len = sizeof(struct sockaddr_storage);
int CLIENT_SOCKET; // contiendra la socket TCP à envoyer sur un THREAD
struct sockaddr_in clientInfo; // contiendra les infos client
socklen_t len; // taille de la socket
int index, i; // compteurs
// retour de @DROP_SERVER
char* serverPort; // contiendra le port
int LISTENSOCK; // contiendra la socket d'écoute
// retour de @DROP_TCP_SERVER
int LISTENSOCK; // contiendra la socket d'écoute TCP
/* [1] On démarre le SERVEUR d'écoute globale
/* [1] On démarre le SERVEUR TCP d'écoute globale
==========================================================*/
serverPort = malloc(maxPortLen);
if( DROP_TCP_SERVER(TCP_PORT, &LISTENSOCK) < 0 ){
// attribution du port si dans les arguments
if( argc > 1 ) strcpy(serverPort, argv[1]);
if( DEBUGMOD&SCK ) printf("\tErreur de mise en place de la socket d'écoute TCP\n");
DROP_SERVER(remoteHost, &serverPort, &LISTENSOCK);
printf("Port: %s\n", serverPort);
// On ferme la SOCKET d'écoute globale
printf("\tFERMETURE DE L'ECOUTE TCP!\n");
close(LISTENSOCK);
return NULL;
}
printf("\tTCP Listen Port: %d\n", TCP_PORT);
/* [2] Attente d'une demande de connection, puis création d'un THREAD
/* [2] Attente d'une demande de connection, pour création d'un THREAD
============================================================================*/
int index = -1;
while( 1 ){
/* 1. On initialise la SOCKET en attendant la connexion et le rang du "manager" inactif */
THREADABLE_SOCKET = -1;
/* 1. On initialise les SOCKET en attendant la connexion et le rang du "manager" inactif */
CLIENT_SOCKET = -1;
index = -1;
/* 2. On attends une connection */
THREADABLE_SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len);
/* 2. On attends une connection TCP */
CLIENT_SOCKET = accept(LISTENSOCK, (struct sockaddr*) &clientInfo, &len);
/* 3. On cherche un "manager" libre */
int i;
/* 3. Si erreur, on attend une nouvelle connection */
if( CLIENT_SOCKET < 0 ){
if( DEBUGMOD&SCK ) printf("\tErreur connection TCP\n");
break;
}
// si on trouve un "manager" inactif, on l'enregistre dans index
for( i = 0 ; i < maxListLen ; i++ )
if( activeManagers[i] == 0 ){ index = i; break; }
/* 4. On cherche un "manager" libre (inactif) */
for( i = 0 ; i < MAX_TCP_THR ; i++ )
if( activeTCPManagers[i] == 0 ){ index = i; break; }
// si on a trouvé un "manager" libre
if( index != -1 ){
/* 4. On lance un thread pour le traitement de ce client */
pthread_create(&managers[index], NULL, manageConnection, (void*)(intptr_t) THREADABLE_SOCKET);
if( DEBUGMOD&THR ) printf("THREAD[%d] démarré\n", index);
/* 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);
/* 6. On signale que ce "manager" est maintenant actif */
activeTCPManagers[index] = 1;
/* 5. On signale que ce "manager" est maintenant actif */
activeManagers[index] = 1;
}else
if( DEBUGMOD&THR ) printf("Demande de thread refusée!\n");
if( DEBUGMOD&THR ) printf("\tAucun thread TCP libre!\n");
}
/* [3] On attends la fin de tous les THREADS
==========================================================*/
int i;
for( i = 0 ; i < maxListLen ; i++ )
pthread_join(managers[i], NULL);
for( i = 0 ; i < MAX_TCP_THR ; i++ )
pthread_join(TCPManagers[i], NULL);
/* [4] On ferme la SOCKET d'écoute globale
==========================================================*/
printf("FERMETURE DE TOUTES LES CONNECTIONS!\n");
printf("FERMETURE DE L'ECOUTE TCP!\n");
close(LISTENSOCK);
return NULL;
}
/* Attente de connection UDP
*
* @history
* [0] Initialisation des variables
* [1] On démarre le SERVEUR UDP d'écoute globale
* [2] On attends un client
* [3] On gère la requête
* [4] On envoie la réponse
* [n] On ferme la SOCKET d'écoute UDP globale
*
*/
void* LISTEN_UDP(){
/* [0] Initialisation des variables
==========================================================*/
struct sockaddr_in clientInfo; // contiendra les infos client
char client_ip[20]; // IP du client
socklen_t len; // taille de la socket
int read; // compteurs
char request[MAX_BUF_LEN] = {0}; // buffer requête
// char response[MAX_BUF_LEN] = {0}; // buffer réponse
// retour de @DROP_UDP_SERVER
int SOCKET;
/* [1] On démarre le SERVEUR UDP d'écoute globale
==========================================================*/
if( DROP_UDP_SERVER(UDP_PORT, &SOCKET) < 0 ){
if( DEBUGMOD&SCK ) printf("\tErreur de mise en place de la socket UDP\n");
// On ferme la SOCKET d'écoute globale
printf("\tFERMETURE DE LA SOCKET UDP!\n");
close(SOCKET);
return NULL;
}
printf("\tUDP Listen Port: %d\n", UDP_PORT);
/* [2] Attente de connection
============================================================================*/
while( 1 ){
/* 0. On vide les données */
bzero(request, MAX_BUF_LEN);
bzero(&clientInfo, sizeof(struct sockaddr_in));
/* 1. On attends une connection UDP */
read = recvfrom(SOCKET, request, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
/* 2. Si erreur reception */
if( read < 0 ){
if( DEBUGMOD&BUF ) printf("\t\t[UDP] READ = %d\n", read);
break;
}
/* 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);
/* 3. Gestion requête */
printf("\t\tRequest(%d bytes) : '%s'\n", read, request);
}
/* [n] On ferme la SOCKET d'écoute globale
==========================================================*/
printf("\tFERMETURE DE LA SOCKET UDP!\n");
close(SOCKET);
return NULL;
}
@ -89,108 +222,62 @@ int main(int argc, char* argv[]){
/* Gestion d'une connexion client
/* Gestion d'une connexion PLANE
*
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
*
* @history
* [1] Initialisation des variables
* [2] Envoi de la séquence de bienvenue
* [3] Attente des données reçues et reception (CLIENT_FTP->PROXY)
* [4] Traitement de la requête client
* [5] Redirection de la requête vers le serveur FTP (PROXY->SERVER_FTP)
* [6] Traitement de la reponse du serveur FTP
* [7] Redirection de la réponse vers le client (PROXY->CLIENT_FTP)
* [8] On vide les buffers
* [9] Fermeture des connections (SOCKETS)
* [10] Arrêt du THREAD
* [2] Récupération de la requête
* [3] Traitement de la requête
* [4] Création de la réponse
* [5] Envoi de la réponse
* [6] On vide les buffers
* [7] Fermeture de la connection (SOCKET)
* [n] Arrêt du THREAD
* 1. On récupère le rang dans les "managers"
* 2. On met à jour "activeManagers"
* 3. On arrête le THREAD
*
*/
void* manageConnection(void* THREADABLE_SOCKET){
int USER_SOCKET = (intptr_t) THREADABLE_SOCKET; // BUS DE COMMANDE utilisateur
void* managePlane(void* THREADABLE_SOCKET){
/* [1] Variables
============================================================================*/
// int USER_SOCKET = -1;
int FTP_SOCKET = -1; // contiendra le BUS DE COMMANDE FTP
int DUSER_SOCKET = -1; // contiendra le BUS DE DONNES utilisateur
int DFTP_SOCKET = -1; // contiendra le BUS DE DONNEES FTP
/* [1] Initialisation des variables
=========================================================*/
int read; // compteur
int TCP_SOCKET = (intptr_t) THREADABLE_SOCKET; // Socket client
char request[MAX_BUF_LEN]; // Requête
// char response[MAX_BUF_LEN]; // Réponse
char* BUFFER; // contiendra le BUFFER
char* ftp_response; // contiendra le BUFFER de réponse du serveur FTP (commandes)
int nbReceived, nbSend; // contiendra les nb reçu && envoyé
BUFFER = malloc( maxBuffLen );
int error;
do{
/* [2] Envoi de la séquence de bienvenue
============================================================================*/
swrite(&USER_SOCKET, WLCM_MSG);
/* [2] Récupération de la requête
=========================================================*/
/* 1. On lit sur la socket */
read = recv(TCP_SOCKET, request, MAX_BUF_LEN, 0);
/* BOUCLE DE COMMANDES */
while( USER_SOCKET != -1 ){
/* [3] On récupère les données reçues (+attente)
============================================================================*/
if( WAIT_SOCKET_UPDATE(&USER_SOCKET, BUFFER) == -1 ) break;
if( DEBUGMOD&CMD ) xPrint("C->P: %s\n", BUFFER);
/* [4] Traitement de la requête
============================================================================*/
error = MANAGE_REQUEST(BUFFER, &USER_SOCKET, &FTP_SOCKET, &DUSER_SOCKET, &DFTP_SOCKET);
// si on a pas la connection FTP (commande) initialisée, on quitte
if( error == -1 ) break;
/* [5] Redirection vers le serveur FTP
============================================================================*/
if( DEBUGMOD&CMD ) xPrint("P->F: %s\n\n", BUFFER);
CLIENT_SEND(&FTP_SOCKET, BUFFER, &BUFFER);
if( DEBUGMOD&CMD ) xPrint("F->P: %s\n", BUFFER);
/* [6] Traitement de la réponse (FTP)
============================================================================*/
MANAGE_RESPONSE(BUFFER, &USER_SOCKET, &FTP_SOCKET, &DUSER_SOCKET, &DFTP_SOCKET);
/* [7] Redirection vers le CLIENT
============================================================================*/
if( swrite(&USER_SOCKET, BUFFER) == -1 ) break;
if( DEBUGMOD&CMD ) xPrint("P->C: %s\n", BUFFER);
/* [8] On vide les buffers
============================================================================*/
memset(BUFFER, '\0', maxBuffLen); // on vide le buffer
memset(BUFFER, '\0', maxBuffLen);
/* 2. Si erreur reception */
if( read < 0 ){
if( DEBUGMOD&BUF ) printf("\t\t[TCP] READ = %d\n", read);
break;
}
/* [9] Fermeture des connections (SOCKETS)
============================================================================*/
printf("CLOSING CONNECTIONS\n");
close(USER_SOCKET);
close(FTP_SOCKET);
printf("\t\tRequest(%d bytes) : '%s'\n", read, request);
/* [10] Arrêt du THREAD
}while( 0 );
/* [n] Arrêt du THREAD
============================================================================*/
/* 1. On récupère le rang dans les "managers" */
int i, index = -1;
for( i = 0 ; i < maxListLen ; i++ )
if( managers[i] == pthread_self() ){ index = i; break; }
for( i = 0 ; i < MAX_TCP_THR ; i++ )
if( TCPManagers[i] == pthread_self() ){ index = i; break; }
/* 2. On met à jour "activeManagers" */
if( index != -1 )
activeManagers[index] = 0;
activeTCPManagers[index] = 0;
/* 3. On arrête le THREAD */
if( DEBUGMOD&THR ) printf("THREAD[%d] libéré\n", index);
if( DEBUGMOD&THR ) printf("\t\tTHREAD[TCP][%d] libéré\n", index);
pthread_exit(NULL);
}

View File

@ -1,57 +1,25 @@
/* global */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <pthread.h>
#include "lib/header.h"
/* sys */
#include <sys/types.h>
#include <sys/socket.h>
/* socket */
#include <netinet/in.h>
#include <netdb.h> // getaddrinfo, getnameinfo
#include <arpa/inet.h>
#include "lib/plane/plane.h"
/* debug */
#define SOCKETS 0x01 // debug RESEAU
#define COMMANDS 0x02 // debug COMMANDES
#define DATA 0x04 // debug DONNEES
#define REVEALS 0x08 // debug EXPLICITATION des strings
#define BUFFERS 0x10 // debug des BUFFERS
#define HEADERS 0x20 // debug des HEADERS de fonctions
#define THREADS 0x40 // debug des THREADS
#define SCK 0x01 // FILTRE pour SOCKET
#define CMD 0x02 // FILTRE pour COMMAND
#define DAT 0x04 // FILTRE pour DATA
#define RVL 0x08 // FILTRE pour REVEALS
#define BUF 0x10 // FILTRE pour BUFFERS
#define HDR 0x20 // FILTRE pour HEADERS
#define THR 0x40 // FILTRE pour THREADS
// possibilité de cumuler les DEBUGMODES
#define DEBUGMOD SOCKETS + THREADS // REVEALS + HEADER + THREADS
/* vars */
#define remoteHost "localhost"
#define remotePort "80"
#define maxBuffLen 4096
#define maxListLen 10
#define maxHostLen 64
#define maxPortLen 6
/* local dependencies */
#include "dep/utility.c"
#include "dep/server.c"
#include "lib/util.h"
#include "lib/network/tcp/server.h"
#include "lib/network/udp/server.h"
/* headers */
void* manageConnection(void* THREADABLE_SOCKET);
void* LISTEN_TCP();
void* LISTEN_UDP();
void* managePlane(void* THREADABLE_SOCKET);
// void* manageViewTerm(void* THREADABLE_SOCKET);
// void* manageCtrlTerm(void* THREADABLE_SOCKET);
// VARIABLES
static pthread_t managers[maxListLen]; // contiendra les THREADS
static int activeManagers[maxListLen] = {0}; // contiendra les THREADS actifs
// VARIABLES THREADS D'ECOUTE TCP/UDP
static pthread_t listenManagers[2]; // contiendra les THREADS d'écoute
// VARIABLES THREADS CONNECTION TCP
static pthread_t TCPManagers[MAX_TCP_THR]; // contiendra les THREADS TCP
static int activeTCPManagers[MAX_TCP_THR] = {0}; // contiendra les THREADS TCP actifs

View File

@ -1,60 +0,0 @@
/* Découpe la requête FTP en 2 parties
*
* @pRequest<char*> La requête en question
*
* @pCommand<char*> Remplissage: commande (1ère partie)
* @pContant<char*> Remplissage: contenu (2ème partie)
*
*
*/
void splitFtpRequest(char* pRequest, char* pCommand, char* pContent);
/* Découpe la réponse FTP en 2 parties
*
* @pAnswer<char*> La réponse en question
*
* @ftpCode<char*> Remplissage: code FTP (1ère partie)
* @ftpText<char*> Remplissage: text associé (2ème partie)
*
*
*/
void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText);
/* Retourne le rang d'un caractère dans une string
*
* @haystack<char*> La chaîne dans laquelle rechercher
* @needle<char> Le caractère recherché
*
* @return position<int> Retourne l'index de @needle dans @haystack ou -1 si ne trouve pas
*
*/
int indexOf(char* haystack, char needle);
void setSocketTimeout(int* pSocket, const int pSec, const int pUSec);
/* read/write socket */
int swrite(int* pSocket, char* pBuffer);
int sread(int* pSocket, char* pBuffer);
/* Affiche une string en supprimant les retours à la ligne de fin de chaînes
*
* @pPattern<char*> Schéma du print (1er arg)
* @pBuffer<char*> Buffer en question
*
*/
void xPrint(char* pPattern, char* pBuffer);
/* Révèle les caractères spéciaux d'une string
*
* @pString<char*> La string à révéler
*
*
* @print explicitString<char*> On affiche la chaîne explicité
*
*/
void revealString(char* pString);

View File

@ -0,0 +1,15 @@
/* debug */
#define SOCKETS 0x01 // debug RESEAU
#define REVEALS 0x02 // debug EXPLICITATION des strings
#define BUFFERS 0x04 // debug des BUFFERS
#define HEADERS 0x08 // debug des HEADERS de fonctions
#define THREADS 0x10 // debug des THREADS
#define SCK 0x01 // FILTRE pour SOCKET
#define RVL 0x02 // FILTRE pour REVEALS
#define BUF 0x04 // FILTRE pour BUFFERS
#define HDR 0x08 // FILTRE pour HEADERS
#define THR 0x10 // FILTRE pour THREADS
// possibilité de cumuler les DEBUGMODES
#define DEBUGMOD ( SOCKETS | THREADS ) // REVEALS + HEADER + THREADS

View File

@ -0,0 +1,37 @@
#ifndef _LIB_HEADER_H_
#define _LIB_HEADER_H_
/* global */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdint.h>
/* sys */
#include <sys/types.h>
#include <sys/socket.h>
/* socket */
#include <unistd.h> // close
#include <netinet/in.h>
#include <netdb.h> // getaddrinfo, getnameinfo
#include <arpa/inet.h>
#include "debug.h"
/* vars */
#define SRV_HOST "localhost"
#define TCP_PORT 4444
#define UDP_PORT 4444
#define MAX_BUF_LEN 512
#define MAX_TCP_THR 10
#define MAX_UDP_THR 10
#define maxHostLen 64
#define maxPortLen 6
#endif

View File

@ -0,0 +1,11 @@
#ifndef _LIB_NETWORK_FORMAT_SERIALIZER_H_
#define _LIB_NETWORK_FORMAT_SERIALIZER_H_
#include "../../header.h";
#endif

View File

@ -0,0 +1,67 @@
#include "server.h"
int DROP_TCP_SERVER(const int pPort, int* pListenSock){
if( DEBUGMOD&HDR ) printf("====== DROP_TCP_SERVER(%d, %p) ======\n\n", pPort, (void*) pListenSock);
/* [0] Initialisation des variables
=========================================================*/
// CREATION
static struct sockaddr_in addr; // contiendra les infos du serveur
int STATUS; // status
// INITIALISATION
*pListenSock = -1;
/* [1] Création de la socket
=======================================================*/
*pListenSock = socket(AF_INET, SOCK_STREAM, 0);
if( DEBUGMOD&SCK ) printf("\t\tTCP SOCKET = %d\n", *pListenSock);
// si erreur
if( *pListenSock < 0 ) return -1;
/* [2] On définit les infos de la socket
=========================================================*/
/* (1) Reset des valeurs */
bzero(&addr, sizeof(struct sockaddr_in));
/* (2) On définit les infos */
addr.sin_family = AF_INET;
addr.sin_port = htons(pPort);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* [3] On publie la SOCKET
=======================================================*/
STATUS = bind(*pListenSock, (struct sockaddr*) &addr, sizeof(addr));
if( DEBUGMOD&SCK ) printf("\t\tTCP BIND = %d\n", STATUS);
// si erreur
if( STATUS < 0 ) return -1;
/* [4] On met la socket sur écoute
=======================================================*/
STATUS = listen(*pListenSock, MAX_TCP_THR);
if( DEBUGMOD&SCK ) printf("\t\tTCP LISTEN = %d\n", STATUS);
// si erreur
if( STATUS < 0 ) return -1;
/* [n] Code succès
=========================================================*/
return 0;
}

View File

@ -0,0 +1,32 @@
#ifndef _LIB_NETWORK_TCP_SERVER_H_
#define _LIB_NETWORK_TCP_SERVER_H_
#include "../../header.h"
/* Créé et met un serveur TCP d'écoute
*
* ==IN==
* @pPort<const int> Port d'écoute TCP
*
* ==OUT==
* @pListenSocket<int*> Pointeur sur le <int> à remplir => contiendra un pointeur sur la socket d'écoute
*
* ==RETURN==
* @status<int> -1 si erreur, sinon 0
*
* @history
* [1] Création de la socket d'écoute
* [2] On définit les infos de la socket
* [3] On publie la SOCKET (bind)
* [4] On met la socket sur écoute (listen)
* [n] On renvoie la socket par référence
*
*/
int DROP_TCP_SERVER(const int pPort, int* pListenSock);
#endif

View File

@ -0,0 +1,58 @@
#include "server.h"
int DROP_UDP_SERVER(const int pPort, int* pListenSock){
if( DEBUGMOD&HDR ) printf("====== DROP_UDP_SERVER(%d, %p) ======\n\n", pPort, (void*) pListenSock);
/* [0] Initialisation des variables
=========================================================*/
// CREATION
static struct sockaddr_in addr; // contiendra les infos du serveur
int STATUS; // status
// INITIALISATION
*pListenSock = -1;
/* [1] Création de la socket
=======================================================*/
*pListenSock = socket(AF_INET, SOCK_DGRAM, 0);
if( DEBUGMOD&SCK ) printf("\t\tUDP SOCKET = %d\n", *pListenSock);
// si erreur
if( *pListenSock < 0 ) return -1;
/* [2] On définit les infos de la socket
=========================================================*/
/* (1) Reset des valeurs */
bzero(&addr, sizeof(struct sockaddr_in));
/* (2) On définit les infos */
addr.sin_family = AF_INET;
addr.sin_port = htons(pPort);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* [3] On publie la SOCKET
=======================================================*/
STATUS = bind(*pListenSock, (struct sockaddr*) &addr, sizeof(addr));
if( DEBUGMOD&SCK ) printf("\t\tUDP BIND = %d\n", STATUS);
// si erreur
if( STATUS < 0 ) return -1;
/* [n] Code succès
=========================================================*/
return 0;
}

View File

@ -0,0 +1,31 @@
#ifndef _LIB_NETWORK_UDP_SERVER_H_
#define _LIB_NETWORK_UDP_SERVER_H_
#include "../../header.h"
/* Créé et met un serveur UDP d'écoute
*
* ==IN==
* @pPort<const int> Port d'écoute UDP
*
* ==OUT==
* @pListenSocket<int*> Pointeur sur le <int> à remplir => contiendra un pointeur sur la socket d'écoute
*
* ==RETURN==
* @status<int> -1 si erreur, sinon 0
*
* @history
* [1] Création de la socket d'écoute
* [2] On définit les infos de la socket
* [3] On publie la SOCKET (bind)
* [n] On renvoie la socket par référence
*
*/
int DROP_UDP_SERVER(const int pPort, int* pListenSock);
#endif

View File

@ -0,0 +1 @@
../../../global/plane.c

View File

@ -0,0 +1 @@
../../../global/plane.h

View File

@ -5,137 +5,14 @@
void DROP_SERVER(const char* serverHost, char** givenPort, int* listenSocket){
if( DEBUGMOD&HDR ) printf("====== DROP_SERVER(%s, %s, %d) ======\n\n", serverHost, *givenPort, *listenSocket);
// FONCTIONNEMENT
struct addrinfo hints; // contiendra le filtre/format
struct addrinfo* addrinfo; // contiendra les infos du serveur
int SOCKET, BIND, LISTEN; // file_desc(s)
// INFOS
struct sockaddr_storage serverInfo; // contiendra les informations du server
socklen_t sockaddr_len = sizeof(struct sockaddr_storage);
char infoHost[maxHostLen]; // contiendra l'adresse du server
char infoPort[maxPortLen]; // contiendra le port du server
/* [1] On définit le filtre/format
=======================================================*/
memset(&hints, 0, sizeof(struct addrinfo)); // on vide le filtre
hints.ai_family = AF_UNSPEC; // Allow IPv4 ou IPv6
hints.ai_socktype = SOCK_STREAM; // TCP (SOCK_DGRAM = UDP)
hints.ai_flags = AI_PASSIVE; // mode SERVER
hints.ai_protocol = 0; // non spécifié
if( DEBUGMOD&SCK ) printf("============HINTS===========\n");
if( DEBUGMOD&SCK ) printf( "AI_FLAGS = %d\n", hints.ai_flags ); // int
if( DEBUGMOD&SCK ) printf( "AI_FAMILY = %d\n", hints.ai_family ); // int
if( DEBUGMOD&SCK ) printf( "AI_SOCKTYPE = %d\n", hints.ai_socktype ); // int
if( DEBUGMOD&SCK ) printf( "AI_PROTOCOL = %d\n", hints.ai_protocol ); // int
if( DEBUGMOD&SCK ) printf( "AI_ADDRLEN = %d\n", hints.ai_addrlen ); // int
if( DEBUGMOD&SCK ) printf("\n");
/* [2] On récupère les infos
=======================================================*/
if( strlen(*givenPort) == 0 ) // si pas défini, port dynamique
getaddrinfo(serverHost, 0, &hints, &addrinfo);
else // sinon manuel
getaddrinfo(serverHost, *givenPort, &hints, &addrinfo);
// Remarque: port=0 donc va être défini dynamiquement
if( DEBUGMOD&SCK ) printf("=============RES============\n");
if( DEBUGMOD&SCK ) printf( "AI_FLAGS = %d\n", addrinfo->ai_flags ); // int
if( DEBUGMOD&SCK ) printf( "AI_FAMILY = %d\n", addrinfo->ai_family ); // int
if( DEBUGMOD&SCK ) printf( "AI_SOCKTYPE = %d\n", addrinfo->ai_socktype ); // int
if( DEBUGMOD&SCK ) printf( "AI_PROTOCOL = %d\n", addrinfo->ai_protocol ); // int
if( DEBUGMOD&SCK ) printf( "AI_ADDRLEN = %d\n", addrinfo->ai_addrlen ); // int
if( DEBUGMOD&SCK ) printf("\n");
/* [3] Création de la socket
=======================================================*/
SOCKET = socket(addrinfo->ai_family, addrinfo->ai_socktype, 0);
if( DEBUGMOD&SCK ) printf("SOCKET = %d\n", SOCKET);
// si erreur
if( SOCKET == -1 ) return;
/* [4] On publie la SOCKET
=======================================================*/
BIND = bind(
SOCKET,
addrinfo->ai_addr,
addrinfo->ai_addrlen
);
if( DEBUGMOD&SCK ) printf("BIND = %d\n", BIND);
// si erreur
if( BIND == -1 ) return;
/* [5] On récupère les informations du serveur (host/port)
=======================================================*/
int getInfo = getsockname(SOCKET, (struct sockaddr *) &serverInfo, &sockaddr_len);
if( getInfo == -1 ) return;
getInfo = getnameinfo( // on récupère le host et le port
(struct sockaddr *) &serverInfo,
sizeof(serverInfo),
infoHost, maxHostLen,
infoPort, maxPortLen,
NI_NUMERICHOST | NI_NUMERICSERV
);
if( getInfo == -1 ) return;
if( DEBUGMOD&SCK ) printf("Server host: %s\n", infoHost);
if( DEBUGMOD&SCK ) printf("Server port: %s\n", infoPort);
// on a plus besoin des infos de l'adresse
freeaddrinfo(addrinfo);
/* [6] On met la socket sur écoute
=======================================================*/
LISTEN = listen(SOCKET, maxListLen);
if( DEBUGMOD&SCK ) printf("LISTEN = %d\n", LISTEN);
// si erreur
if( LISTEN == -1 ) return;
/* [7] On envoie les données par référence
=======================================================*/
// port
*givenPort = malloc( maxPortLen );
strcpy(*givenPort, infoPort);
// socket d'écoute
*listenSocket = SOCKET;
}
int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET){
if( DEBUGMOD&HDR ) printf("====== MANAGE_REQUEST(%s, %d, %d, %d, %d) ======\n\n", pRequest, *USER_SOCKET, *FTP_SOCKET, *DUSER_SOCKET, *DFTP_SOCKET);
char response[maxBuffLen]; // contiendra la réponse (2*taille buffer pour strcat(BUFLEN, BUFLEN))
char response[MAX_BUF_LEN]; // contiendra la réponse (2*taille buffer pour strcat(BUFLEN, BUFLEN))
int nbSend; // contiendra le nombre de données envoyées
char rCommand[5]; // contiendra les commandes (1ère partie)
char rContent[maxBuffLen]; // contiendra le contenu associé à la commande (2ème partie)
char rContent[MAX_BUF_LEN]; // contiendra le contenu associé à la commande (2ème partie)
// on vide les buffers
memset(&rCommand, '\0', sizeof(rCommand));
@ -157,8 +34,8 @@ int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER
char userName[100] = {0};
char hostName[maxHostLen] = {0};
// pour l'envoi de la séquence d'initialisation
char* ftp_response; ftp_response = malloc(maxBuffLen);
memset(ftp_response, 0, maxBuffLen);
char* ftp_response; ftp_response = malloc(MAX_BUF_LEN);
memset(ftp_response, 0, MAX_BUF_LEN);
/* 1. On extrait @username et @hostname */
sscanf(rContent, "%[^@]@%s\r\n", userName, hostName);
@ -187,7 +64,7 @@ int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER
/* 4. On envoie la requête USER au serveur FTP auquel on vient de se connecter */
char newRequest[maxBuffLen];
char newRequest[MAX_BUF_LEN];
strcat(newRequest, "USER ");
strcat(newRequest, userName);
strcat(newRequest, "\r\n");
@ -205,7 +82,7 @@ int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER
char serverHost[maxHostLen] = {0};
char serverPort[maxPortLen] = {0};
char BUFFER[maxBuffLen] = {0};
char BUFFER[MAX_BUF_LEN] = {0};
/* 1. On récupère l'ip et le port de la réponse */
sscanf(pRequest, "PORT %d,%d,%d,%d,%d,%d", &a1, &a2, &a3, &a4, &p1, &p2);
@ -243,9 +120,9 @@ int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER
void MANAGE_RESPONSE(char* pAnswer, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET){
if( DEBUGMOD&HDR ) printf("====== MANAGE_RESPONSE(%s, %d, %d, %d, %d) ======\n\n", pAnswer, *USER_SOCKET, *FTP_SOCKET, *DUSER_SOCKET, *DFTP_SOCKET);
char response[maxBuffLen]; // contiendra la réponse
char response[MAX_BUF_LEN]; // contiendra la réponse
char ftpCodeStr[4]; // contiendra le code FTP (1ère partie)
char ftpText[maxBuffLen]; // contiendra le texte associé à la commande (2ème partie)
char ftpText[MAX_BUF_LEN]; // contiendra le texte associé à la commande (2ème partie)
int ftpCode; // contiendra le code FTP en numérique
// on vide les buffers
@ -265,7 +142,7 @@ void MANAGE_RESPONSE(char* pAnswer, int* USER_SOCKET, int* FTP_SOCKET, int* DUSE
int tmp[6] = {0};
char serverHost[maxHostLen];
char serverPort[maxPortLen];
char BUFFER[maxBuffLen] = {0};
char BUFFER[MAX_BUF_LEN] = {0};
/* [2] Selection en fonction de @ftpCode
================================================*/
@ -409,7 +286,7 @@ void MANAGE_RESPONSE(char* pAnswer, int* USER_SOCKET, int* FTP_SOCKET, int* DUSE
int WAIT_SOCKET_UPDATE(int* pSocket, char* pBuffer){
memset(pBuffer, 0, maxBuffLen); // on vide le buffer
memset(pBuffer, 0, MAX_BUF_LEN); // on vide le buffer
int nbRead = 0;

View File

@ -1,27 +1,4 @@
/* Créé et met un serveur sur écoute
*
* ==IN==
* @serverHost<char*> Nom de l'hôte local (localhost)
* @givenPort<char**> Si renseigné, définit le port à utiliser
*
* ==OUT==
* @givenPort<char**> Pointeur sur le <char*> à remplir => contiendra le port donné par le système (si pas renseigné en entrée)
* @listenSocket<int*> Pointeur sur le <int> à remplir => contiendra un pointeur sur la socket d'écoute
*
*
*
* @history
* [1] On définit le filtre/format
* [2] On récupère les infos (adresse, port)
* Note: Gestion IPv4/IPv6
* [3] Création de la socket
* [4] On publie la SOCKET (bind)
* [5] On récupère les informations du serveur (host/port)
* [6] On met la socket sur écoute (listen)
* [7] On envoie les données par référence
*
*/
void DROP_SERVER(const char* serverHost, char** givenPort, int* listenSocket);
#include "server.h"

View File

@ -1,69 +1,4 @@
#include "utility.h"
void splitFtpRequest(char* pRequest, char* pCommand, char* pContent){
/* [1] Vérification du format
===========================================*/
int firstSpaceIndex = indexOf(pRequest, ' ');
if( firstSpaceIndex != 3 && firstSpaceIndex != 4){ // contient aucun espace en position 3 ou 4, on quitte
strcpy(pCommand, "ERROR");
strcpy(pContent, "");
return;
}
/* [2] Séparation des 2 parties
===========================================*/
int i;
for( i = 0 ; i < strlen(pRequest) && pRequest[i] != '\0' ; i++ ){
if( i < firstSpaceIndex ) // première partie (pCommand)
strcat( pCommand, (char[2]){(char) pRequest[i], '\0'});
if( i > firstSpaceIndex ) // seconde partie (pContent)
strcat( pContent, (char[2]){(char) pRequest[i], '\0'});
}
}
void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText){
/* [1] Vérification du format
===========================================*/
int codeLength = 3; // taille du code
/* [2] Séparation des 2 parties
===========================================*/
int i;
for( i = 0 ; i < strlen(pAnswer) && pAnswer[i] != '\0' ; i++ ){
if( i < codeLength ) // première partie (ftpCode)
strcat(ftpCode, (char[2]){(char)pAnswer[i], '\0' });
if( i > codeLength ) // seconde partie (ftpText)
strcat(ftpText, (char[2]){(char)pAnswer[i], '\0' });
}
}
int indexOf(char* haystack, char needle){
int i;
for( i = 0 ; i < strlen(haystack) && haystack[i] != '\0' ; i++ )
if( haystack[i] == needle ) // si on trouve le caractère
return i;
return -1;
}
#include "util.h"
int swrite(int* pSocket, char* pBuffer){
@ -97,11 +32,11 @@ int sread(int* pSocket, char* pBuffer){
/* 1. On vide le buffer avant de lire */
memset(pBuffer, '\0', maxBuffLen);
memset(pBuffer, '\0', MAX_BUF_LEN);
if( DEBUGMOD&BUF ) printf("READLEN_1: %lu\n", strlen(pBuffer));
/* 2. On lit la SOCKET */
int nbRead = read(*pSocket, pBuffer, maxBuffLen);
int nbRead = read(*pSocket, pBuffer, MAX_BUF_LEN);
if( DEBUGMOD&BUF ) printf("READLEN_3: %d\n", nbRead);
@ -133,7 +68,7 @@ void setSocketTimeout(int* pSocket, const int pSec, const int pUSec){
void xPrint(char* pPattern, char* pBuffer){
char tmpBuffer[maxBuffLen];
char tmpBuffer[MAX_BUF_LEN];
strcpy(tmpBuffer, pBuffer);
@ -152,7 +87,7 @@ void xPrint(char* pPattern, char* pBuffer){
void revealString(char* pString){
/* 1. On créé une copie de @pString */
char revealedString[maxBuffLen] = {0};
char revealedString[MAX_BUF_LEN] = {0};
/* 2. On rend visible tous les caractères "invisibles" */
int i;

View File

@ -0,0 +1,29 @@
#include "header.h"
void setSocketTimeout(int* pSocket, const int pSec, const int pUSec);
/* read/write socket */
int swrite(int* pSocket, char* pBuffer);
int sread(int* pSocket, char* pBuffer);
/* Affiche une string en supprimant les retours à la ligne de fin de chaînes
*
* @pPattern<char*> Schéma du print (1er arg)
* @pBuffer<char*> Buffer en question
*
*/
void xPrint(char* pPattern, char* pBuffer);
/* Révèle les caractères spéciaux d'une string
*
* @pString<char*> La string à révéler
*
*
* @print explicitString<char*> On affiche la chaîne explicité
*
*/
void revealString(char* pString);

167
global/plane.c Normal file
View File

@ -0,0 +1,167 @@
#include <math.h>
#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.altitude = 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'altitude de l'avion avec la valeur passée en paramètre
void changer_altitude(int alt)
{
if (alt < 0)
coord.altitude = 0;
else if (alt > ALTMAX)
coord.altitude = ALTMAX;
else coord.altitude = alt;
}
// affiche les caractéristiques courantes de l'avion
void afficher_donnees()
{
printf("Avion %s -> localisation : (%d,%d), altitude : %d, vitesse : %d, cap : %d\n",
numero_vol, coord.x, coord.y, coord.altitude, 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.altitude == 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();
}

18
global/plane.h Normal file
View File

@ -0,0 +1,18 @@
#define ALTMAX 20000
#define ALTMIN 0
#define VITMAX 1000
#define VITMIN 200
#define PAUSE 2
struct coordonnees {
int x;
int y;
int altitude;
};
struct deplacement {
int cap;
int vitesse;
};

View File

@ -304,7 +304,7 @@
<li class="L8" rel="L8"> struct addrinfo* addrinfo; // contiendra les infos</li>
<li class="L9" rel="L9"> int CONNECT; // file_desc(s)</li>
<li class="L10" rel="L10"> int GETADDRINFO; // contiendra l&#39;erreur ou pas de getaddrinfo()</li>
<li class="L11" rel="L11"> char BUFFER[maxBuffLen]; // BUFFER de communication</li>
<li class="L11" rel="L11"> char BUFFER[MAX_BUF_LEN]; // BUFFER de communication</li>
<li class="L12" rel="L12"></li>
<li class="L13" rel="L13"> /* [1] On définit le filtre/format</li>
<li class="L14" rel="L14"> =======================================================*/</li>
@ -377,7 +377,7 @@
<li class="L81" rel="L81"></li>
<li class="L82" rel="L82">int CLIENT_SEND(int* pSocket, char* pRequest, char** pAnswer){</li>
<li class="L83" rel="L83"> if( DEBUGMOD&amp;HDR ) printf(&#34;====== CLIENT_SEND(%d, %s, %s) ======\n\n&#34;, *pSocket, pRequest, *pAnswer);</li>
<li class="L84" rel="L84"> char BUFFER[maxBuffLen] = {0};</li>
<li class="L84" rel="L84"> char BUFFER[MAX_BUF_LEN] = {0};</li>
<li class="L85" rel="L85"></li>
<li class="L86" rel="L86"> /* [1] On écrit sur la socket</li>
<li class="L87" rel="L87"> =======================================================*/</li>
@ -395,7 +395,7 @@
<li class="L99" rel="L99"></li>
<li class="L100" rel="L100"> /* [3] On retourne la réponse par référence</li>
<li class="L101" rel="L101"> =======================================================*/</li>
<li class="L102" rel="L102"> *pAnswer = malloc( maxBuffLen );</li>
<li class="L102" rel="L102"> *pAnswer = malloc( MAX_BUF_LEN );</li>
<li class="L103" rel="L103"> strcpy(*pAnswer, BUFFER);</li>
<li class="L104" rel="L104"></li>
<li class="L105" rel="L105"> if( DEBUGMOD&amp;BUF ) printf(&#34;nbReceived: %d\n&#34;, nbRecup);</li>

View File

@ -97,11 +97,11 @@ int sread(int* pSocket, char* pBuffer){
/* 1. On vide le buffer avant de lire */
memset(pBuffer, '\0', maxBuffLen);
memset(pBuffer, '\0', MAX_BUF_LEN);
if( DEBUGMOD&BUF ) printf("READLEN_1: %lu\n", strlen(pBuffer));
/* 2. On lit la SOCKET */
int nbRead = read(*pSocket, pBuffer, maxBuffLen);
int nbRead = read(*pSocket, pBuffer, MAX_BUF_LEN);
if( DEBUGMOD&BUF ) printf("READLEN_3: %d\n", nbRead);
@ -133,7 +133,7 @@ void setSocketTimeout(int* pSocket, const int pSec, const int pUSec){
void xPrint(char* pPattern, char* pBuffer){
char tmpBuffer[maxBuffLen];
char tmpBuffer[MAX_BUF_LEN];
strcpy(tmpBuffer, pBuffer);
@ -152,7 +152,7 @@ void xPrint(char* pPattern, char* pBuffer){
void revealString(char* pString){
/* 1. On créé une copie de @pString */
char revealedString[maxBuffLen] = {0};
char revealedString[MAX_BUF_LEN] = {0};
/* 2. On rend visible tous les caractères "invisibles" */
int i;