Lib tcp/udp in progress
This commit is contained in:
parent
b41a8d304f
commit
94c4769241
|
@ -0,0 +1 @@
|
|||
.vscode
|
|
@ -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
|
|
@ -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
|
||||
* [3] On attends la fin de tous les THREADS
|
||||
* [4] On ferme la SOCKET d'écoute globale
|
||||
* [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;
|
||||
index = -1;
|
||||
|
||||
/* 2. On attends une connection */
|
||||
THREADABLE_SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len);
|
||||
/* 1. On initialise les SOCKET en attendant la connexion et le rang du "manager" inactif */
|
||||
CLIENT_SOCKET = -1;
|
||||
index = -1;
|
||||
|
||||
/* 3. On cherche un "manager" libre */
|
||||
int i;
|
||||
/* 2. On attends une connection TCP */
|
||||
CLIENT_SOCKET = accept(LISTENSOCK, (struct sockaddr*) &clientInfo, &len);
|
||||
|
||||
// si on trouve un "manager" inactif, on l'enregistre dans index
|
||||
for( i = 0 ; i < maxListLen ; i++ )
|
||||
if( activeManagers[i] == 0 ){ index = i; break; }
|
||||
/* 3. Si erreur, on attend une nouvelle connection */
|
||||
if( CLIENT_SOCKET < 0 ){
|
||||
if( DEBUGMOD&SCK ) printf("\tErreur connection TCP\n");
|
||||
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 ){
|
||||
/* 2. Si erreur reception */
|
||||
if( read < 0 ){
|
||||
if( DEBUGMOD&BUF ) printf("\t\t[TCP] READ = %d\n", read);
|
||||
break;
|
||||
}
|
||||
|
||||
/* [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);
|
||||
printf("\t\tRequest(%d bytes) : '%s'\n", read, request);
|
||||
|
||||
}while( 0 );
|
||||
|
||||
/* [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);
|
||||
}
|
||||
|
||||
/* [9] Fermeture des connections (SOCKETS)
|
||||
============================================================================*/
|
||||
printf("CLOSING CONNECTIONS\n");
|
||||
close(USER_SOCKET);
|
||||
close(FTP_SOCKET);
|
||||
|
||||
/* [10] Arrêt du THREAD
|
||||
/* [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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef _LIB_NETWORK_FORMAT_SERIALIZER_H_
|
||||
#define _LIB_NETWORK_FORMAT_SERIALIZER_H_
|
||||
|
||||
|
||||
#include "../../header.h";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
../../../global/plane.c
|
|
@ -0,0 +1 @@
|
|||
../../../global/plane.h
|
|
@ -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;
|
||||
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
@ -1,74 +1,9 @@
|
|||
#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){
|
||||
if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur
|
||||
if( strlen(pBuffer) == 0 ) return 0; // si on a rien à écrire, on n'écrit rien :p
|
||||
if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur
|
||||
if( strlen(pBuffer) == 0 ) return 0; // si on a rien à écrire, on n'écrit rien :p
|
||||
|
||||
|
||||
/* 1. On écrit sur la SOCKET */
|
||||
|
@ -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,14 +87,14 @@ 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;
|
||||
for( i = 0 ; i < strlen(pString) && pString[i] != '\0' ; i++ ){
|
||||
if( pString[i] == '\r' ){ revealedString[strlen(revealedString)] = '\\'; revealedString[strlen(revealedString)] = 'r'; }
|
||||
else if( pString[i] == '\n' ){ revealedString[strlen(revealedString)] = '\\'; revealedString[strlen(revealedString)] = 'n'; }
|
||||
else revealedString[strlen(revealedString)] = pString[i];
|
||||
else revealedString[strlen(revealedString)] = pString[i];
|
||||
|
||||
revealedString[strlen(revealedString)] = '\0';
|
||||
}
|
|
@ -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);
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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'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&HDR ) printf("====== CLIENT_SEND(%d, %s, %s) ======\n\n", *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&BUF ) printf("nbReceived: %d\n", nbRecup);</li>
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue