Browse Source

:sparkles: Reception & traitement requete client

Arthur Brandao 6 năm trước cách đây
mục cha
commit
822a1030f7

+ 3 - 3
Serveur/arraylist.c

@@ -17,7 +17,7 @@ void arraylist_ini(arraylist* al){
     al->size = 0;
 }
 
-al_node* arraylist_add(arraylist* al, char* key, int(*handler)(Server, JsonParser*)){
+al_node* arraylist_add(arraylist* al, char* key, int(*handler)(int, JsonParser*)){
     int length;
     al_node* aln;
     //Regarde si la clef existe
@@ -63,12 +63,12 @@ al_node* arraylist_search(arraylist* al, char* key){
     return NULL;
 }
 
-int arraylist_call(arraylist* al, char* key, Server serv, JsonParser* arg){
+int arraylist_call(arraylist* al, char* key, int cliId, JsonParser* arg){
     al_node* aln = arraylist_search(al, key);
     if(aln == NULL){
         return -1;
     }
-    return aln->handler(serv, arg);
+    return aln->handler(cliId, arg);
 }
 
 void arraylist_delete(arraylist* al, al_node* aln){

+ 6 - 5
Serveur/arraylist.h

@@ -17,7 +17,7 @@
 typedef struct al_node al_node;
 struct al_node{
     char* key; //Clef d'accès
-    int(*handler)(Server, JsonParser*); //Fonction
+    int(*handler)(int, JsonParser*); //Fonction
     al_node* prev; //Noeud precedent
     al_node* next; //Noeud suivant
 };
@@ -39,10 +39,10 @@ void arraylist_ini(arraylist*);
  * Si un noeud du meme nom existe deja le remplace
  * @param arraylist* Arraylist d'accueil
  * @param char* clef
- * @param int(*)(char*) Fonction
+ * @param int(*)(int, JsonParser*) Fonction
  * @return al_node* Le noeud ajouté
  */
-al_node* arraylist_add(arraylist*, char*, int(*)(Server, JsonParser*));
+al_node* arraylist_add(arraylist*, char*, int(*)(int, JsonParser*));
 
 /**
  * Cherche un noeud
@@ -56,10 +56,11 @@ al_node* arraylist_search(arraylist*, char*);
  * Appel la fonction d'un noeud
  * @param arraylist* Arraylist du noeud
  * @param char* Clef du noeud
- * @param char* Argument pour la fonction
+ * @param int Id du client
+ * @param JsonParser* Argument pour la fonction
  * @return int Resultat de la fonction ou -1 si introuvable
  */
-int arraylist_call(arraylist*, char*, Server, JsonParser*);
+int arraylist_call(arraylist*, char*, int, JsonParser*);
 
 /**
  * Supprime un noeud

+ 134 - 51
Serveur/bomberstudent_server.c

@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>
+#include <signal.h>
 #include "arraylist.h"
 #include "bomberstudent_server.h"
 #include "error.h"
@@ -17,25 +18,61 @@ arraylist get;
 arraylist post;
 
 /* --- Fonctions privées --- */
-void* udp_thread(void* data){
+
+/**
+ * Thread de gestion d'un client
+ * @param data
+ * @return 
+ */
+void* client_thread(void* data) {
+    int* tmp, cliId, nbError = 0;
+    Client* cli;
+    //Recup la valeur de data
+    tmp = (int*) data;
+    cliId = *tmp;
+    //Recup le client
+    cli = get_client(cliId);
+    if (cli == NULL) {
+        adderror("Le client n'existe pas");
+        return NULL;
+    }
+    //Attente requete du client
+    while (true) {
+        if (!receive_client(cli)) {
+            adderror("Erreur lors de la reception d'une requete du client");
+            nbError++;
+        } else {
+            nbError = 0;
+        }
+        //Si trop d'erreur d'affilé
+        if (nbError == NBERRORRESET) {
+            //Fermeture du client et fin du thread
+            remove_client(cliId);
+            break;
+        }
+    }
+    return NULL;
+}
+
+void* udp_thread(void* data) {
     Server s;
     char buffer[BUFFER_SIZE];
     //Cast data en serveur
     s = (Server) data;
     //Detache le thread
-    if(pthread_detach(pthread_self()) != 0){
+    if (pthread_detach(pthread_self()) != 0) {
         return NULL;
     }
     //Boucle attente
-    while(true){
+    while (true) {
         //Attente connexion
-        if(s->server_receive(s, buffer, BUFFER_SIZE) == ERR){
+        if (s->server_receive(s, buffer, BUFFER_SIZE) == ERR) {
             addserror("Impossible de recevoir le demande de recherche");
             continue;
         }
         //Si la phrase est correcte
-        if(strncmp(buffer, SEARCH_SERV, strlen(buffer)) == 0){
-            if(!s->server_send(s, "i'm a bomberstudent server")){
+        if (strncmp(buffer, SEARCH_SERV, strlen(buffer)) == 0) {
+            if (!s->server_send(s, "i'm a bomberstudent server")) {
                 addserror("Impossible de repondre à la recherche");
             }
         }
@@ -43,68 +80,64 @@ void* udp_thread(void* data){
     return NULL;
 }
 
-//Thread initialisation de la communication principale entre client et serveur
-//Connexion utilisé pour traiter les requetes emise par le client
-void* tcp_cli_thread(void* data){
-    Server s;
-    //Cast data en serveur
-    s = (Server) data;
-    //Detache le thread
-    if(pthread_detach(pthread_self()) != 0){
-        return NULL;
-    }
-    //Boucle attente
-    while(true){
-        
-    }
-    return NULL;
-}
-
-//Thread initialisation de la communication utilisé par le serveur pour notifier les clients
-void* tcp_serv_thread(void* data){
-    Server s;
+void* tcp_thread(void* data) {
+    Server* s;
+    boolean res;
+    int cliId;
+    pthread_t client;
     //Cast data en serveur
-    s = (Server) data;
+    s = (Server*) data;
     //Detache le thread
-    if(pthread_detach(pthread_self()) != 0){
+    if (pthread_detach(pthread_self()) != 0) {
         return NULL;
     }
     //Boucle attente
-    while(true){
-        
+    while (true) {
+        res = s[0]->server_accept(s[0]);
+        res = res && s[1]->server_accept(s[1]);
+        if (!res) {
+            addserror("Impossible d'etablir la connexion TCP");
+            continue;
+        }
+        //Creation d'un client et de son thread
+        cliId = add_client(s[0], s[1]);
+        if (pthread_create(&client, NULL, client_thread, &cliId) != 0) {
+            adderror("Impossible de créer le thread CLient");
+            /*ToDo Avertir Client du probleme*/
+        }
     }
     return NULL;
 }
 
 /* --- Fonctions publiques --- */
-void ini_server(){
+void ini_server() {
     arraylist_ini(&get);
     arraylist_ini(&post);
 }
 
-void add_handler(char* method, char* ressource, int(*handler)(Server, JsonParser*)){
-    if(strncmp(method, "POST", 5) == 0){
+void add_handler(char* method, char* ressource, int(*handler)(int, JsonParser*)) {
+    if (strncmp(method, "POST", 5) == 0) {
         arraylist_add(&post, ressource, handler);
-    } else if(strncmp(method, "POST", 5) == 0){
+    } else if (strncmp(method, "POST", 5) == 0) {
         arraylist_add(&get, ressource, handler);
     }
 }
 
-boolean launch_udp_server(int port){
+boolean launch_udp_server(int port) {
     Server s;
     pthread_t udp;
     //Creation serveur
     s = server_create_udp();
-    if(s == NULL){
+    if (s == NULL) {
         addserror("Impossible de créer le serveur UDP");
         return false;
     }
-    if(!s->server_bind(s, port)){
+    if (!s->server_bind(s, port)) {
         addserror("Impossible de bind le serveur UDP");
         return false;
     }
     //Lancement thread serveur udp
-    if(pthread_create(&udp, NULL, udp_thread, s) != 0){
+    if (pthread_create(&udp, NULL, udp_thread, s) != 0) {
         adderror("Impossible de créer le thread UDP");
         server_close(s);
         return false;
@@ -112,36 +145,86 @@ boolean launch_udp_server(int port){
     return true;
 }
 
-boolean launch_tcp_server(int port){
-    Server s[2];
+boolean launch_tcp_server(int port) {
+    Server* s;
     pthread_t tcp;
     //Creation serveur
+    s = malloc(sizeof (Server) * 2);
     s[0] = server_create_tcp();
     s[1] = server_create_tcp();
-    if(s[0] == NULL || s[1] == NULL){
+    if (s[0] == NULL || s[1] == NULL) {
         addserror("Impossible de créer les serveurs TCP");
         return false;
     }
-    if(!( s[0]->server_bind(s[0], port) && s[1]->server_bind(s[1], port + 1) )){
+    if (!(s[0]->server_bind(s[0], port) && s[1]->server_bind(s[1], port + 1))) {
         addserror("Impossible de bind les serveurs TCP");
         return false;
     }
     //Lancement Thread attente connexion TCP 
-    if(pthread_create(&tcp, NULL, tcp_cli_thread, s[0]) != 0){
-        adderror("Impossible de créer le thread TCP Client");
+    if (pthread_create(&tcp, NULL, tcp_thread, s) != 0) {
+        adderror("Impossible de créer le thread TCP");
         server_close(s[0]);
         server_close(s[1]);
         return false;
     }
-    if(pthread_create(&tcp, NULL, tcp_serv_thread, s[1]) != 0){
-        adderror("Impossible de créer le thread TCP Serveur");
-        server_close(s[0]);
-        server_close(s[1]);
+    return true;
+}
+
+boolean receive_client(Client* cli) {
+    char buffer[BUFFER_SIZE];
+    char* reader, * ressource, * json = NULL;
+    int method, pos, compteur = 0;
+    JsonParser* jp = NULL;
+    arraylist* al = &get;
+    //Attente reception
+    printf("Ici\n");
+    if (cli->main->server_receive(cli->main, buffer, BUFFER_SIZE) == ERR) {
+        addserror("Impossible de recevoire les données du client");
+        return false;
+    }
+    //Recup la methode
+    if (buffer[0] == 'P') {
+        pos = 5;
+        reader = buffer + pos;
+        method = POST;
+    } else if (buffer[0] == 'G') {
+        pos = 4;
+        reader = buffer + pos;
+        method = GET;
+    } else {
+        //Methode incorrect
+        return false;
+    }
+    //Recup la ressource
+    while (buffer[pos] != '\n' && buffer[pos] != '\0') {
+        compteur++;
+        pos++;
+    }
+    if (compteur == 0) {
+        return false;
+    }
+    ressource = malloc(sizeof (char) * compteur);
+    strncpy(ressource, reader, compteur);
+    //Recup param JSON
+    if (method == POST) {
+        if (buffer[pos] == '\0') {
+            //Pas de parametre avec le post
+            return false;
+        }
+        json = reader + compteur + 1;
+        jp = malloc(sizeof (JsonParser));
+        if (json_parse(jp, json) != JSON_OK) {
+            return false;
+        }
+        //Change la liste à utiliser
+        al = &post;
+    }
+    //Appel le callback
+    if (arraylist_call(al, ressource, cli->id, jp) == ERR) {
         return false;
     }
     return true;
 }
 
-boolean receive_client(Server);
-boolean send_client(Server, JsonEncoder*);
-boolean notify_client(Server, char*, char*, JsonEncoder*);
+boolean send_client(Client* cli, JsonEncoder* answer);
+boolean notify_client(Client* cli, char* method, char* ressource, JsonEncoder* param);

+ 5 - 4
Serveur/bomberstudent_server.h

@@ -12,6 +12,7 @@
 #include "constante.h"
 #include "server.h"
 #include "json.h"
+#include "client.h"
 
 /* --- Constantes --- */
 #define PORT_UDP 18624
@@ -19,12 +20,12 @@
 
 /* --- Fonctions --- */
 void ini_server();
-void add_handler(char*, char*, int(*)(Server, JsonParser*));
+void add_handler(char*, char*, int(*)(int, JsonParser*));
 boolean launch_udp_server(int);
 boolean launch_tcp_server(int);
-boolean receive_client(Server);
-boolean send_client(Server, JsonEncoder*);
-boolean notify_client(Server, char*, char*, JsonEncoder*);
+boolean receive_client(Client*);
+boolean send_client(Client*, JsonEncoder*);
+boolean notify_client(Client*, char*, char*, JsonEncoder*);
 
 #endif /* BOMBERSTUDENT_SERVER_H */
 

+ 28 - 0
Serveur/bomberstudent_server.log

@@ -0,0 +1,28 @@
+----- Log processus 8588 (timestamp : 1542806025) -----
+Erreur dans le fichier bomberstudent_server.c ligne 41, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 41, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 41, Erreur lors de la reception d'une requete du client
+----- Fin log processus 8588 (temps en seconde : 60) -----
+----- Log processus 8691 (timestamp : 1542806438) -----
+----- Log processus 8706 (timestamp : 1542806486) -----
+----- Log processus 8733 (timestamp : 1542806547) -----
+----- Log processus 8766 (timestamp : 1542806631) -----
+----- Fin log processus 8766 (temps en seconde : 60) -----
+----- Log processus 8810 (timestamp : 1542806794) -----
+----- Fin log processus 8810 (temps en seconde : 60) -----
+eur dans le fichier server_udp.c ligne 31, Impossible de bind la socket : Address already in use
+Erreur dans le fichier bomberstudent_server.c ligne 135, Impossible de bind le serveur UDP : Erreur lors du bind de la socket
+----- Fin log processus 8815 (temps en seconde : 0) -----
+----- Log processus 8860 (timestamp : 1542806868) -----
+Erreur dans le fichier bomberstudent_server.c ligne 41, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 41, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 41, Erreur lors de la reception d'une requete du client
+----- Log processus 9227 (timestamp : 1542807502) -----
+Erreur dans le fichier bomberstudent_server.c ligne 42, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 42, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 42, Erreur lors de la reception d'une requete du client
+----- Fin log processus 9227 (temps en seconde : 60) -----
+----- Log processus 9276 (timestamp : 1542807569) -----
+Erreur dans le fichier bomberstudent_server.c ligne 42, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 42, Erreur lors de la reception d'une requete du client
+Erreur dans le fichier bomberstudent_server.c ligne 42, Erreur lors de la reception d'une requete du client

+ 90 - 0
Serveur/client.c

@@ -0,0 +1,90 @@
+/* 
+ * File:   client.c
+ * Author: Arthur Brandao
+ *
+ * Created on 21 novembre 2018
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "client.h"
+
+/* --- Globale --- */
+int id = 0;
+ClientList clist;
+
+/* --- Fonctions publiques ---*/
+int add_client(Server cli, Server serv){
+    //Creation client
+    Client* c = malloc(sizeof(Client));
+    c->main = cli;
+    c->notify = serv;
+    c->id = id++;
+    //Creation noeud
+    ClientNode* cn = malloc(sizeof(ClientNode));
+    cn->cli = c;
+    cn->next = NULL;
+    cn->empty = false;
+    //Ajout dans la liste
+    if(clist.length == 0){
+        clist.tab = cn;
+    } else {
+        ClientNode* lastcn = clist.tab;
+        for(int i = 0; i < clist.length - 1; i++){
+            lastcn = lastcn->next;
+        }
+        lastcn->next = cn;
+    }
+    clist.length++;
+    //Retourne l'id du client
+    return c->id;
+}
+
+Client* get_client(int id){
+    //Si hors du tableau
+    if(id >= clist.length){
+        return NULL;
+    }
+    //Recup le noeud
+    ClientNode* cn = clist.tab;
+    for(int i = 0; i < id; i++){
+        cn = cn->next;
+    }
+    //Si client suppr
+    if(cn->empty){
+        return NULL;
+    }
+    return cn->cli;
+}
+
+void remove_client(int id){
+    //Si hors du tableau
+    if(id >= clist.length){
+        return;
+    }
+    //Recup le noeud
+    ClientNode* cn = clist.tab;
+    for(int i = 0; i < id; i++){
+        cn = cn->next;
+    }
+    //Supprime le client
+    server_close_client(cn->cli->main);
+    server_close_client(cn->cli->notify);
+    free(cn->cli);
+    cn->empty = true;
+}
+
+void clean_clientlist(){
+    ClientNode* tmp;
+    ClientNode* cn = clist.tab;
+    for(int i = 0; i < clist.length; i++){
+        if(!cn->empty){
+            remove_client(i);
+        }
+        tmp = cn;
+        cn = cn->next;
+        free(tmp);
+    }
+    clist.length = 0;
+    clist.tab = NULL;
+}

+ 39 - 0
Serveur/client.h

@@ -0,0 +1,39 @@
+/* 
+ * File:   client.h
+ * Author: Arthur Brandao
+ *
+ * Created on 21 novembre 2018
+ */
+
+#ifndef CLIENT_H
+#define CLIENT_H
+
+/* --- Include --- */
+#include "constante.h"
+#include "server.h"
+
+/* --- Strcutures --- */
+typedef struct{
+    int id; //Id unique du client
+    Server main; //Connexion principale entre le client et le serveur
+    Server notify; //Connexion pour notifier le client
+}Client;
+typedef struct ClientNode ClientNode;
+struct ClientNode{
+    boolean empty;
+    Client* cli;
+    ClientNode* next;
+};
+typedef struct{
+    int length;
+    ClientNode* tab;
+}ClientList;
+
+/* --- Fonctions --- */
+int add_client(Server, Server);
+Client* get_client(int);
+void remove_client(int);
+void clean_clientlist();
+
+#endif /* CLIENT_H */
+

+ 5 - 0
Serveur/constante.h

@@ -25,6 +25,11 @@
 #define null NULL
 
 /* --- Application --- */
+#define GET 1
+#define POST 2
+#define NBERRORRESET 3 //Nombre d'erreur avant de considérer que la connexion comme fermée 
+
+/* --- Reseaux --- */
 #define PORT_UDP 18624
 #define PORT_TCP 18642
 #define SEARCH_SERV "looking for bomberstudent servers"

+ 1 - 1
Serveur/json.h

@@ -83,7 +83,7 @@ char* get_index(JsonParser*, int);
 int get_pos(JsonParser*, char*);
 
 /**
- * Retourne le type de la vl=aleur
+ * Retourne le type de la valeur
  * @param JsonParser* Le resultat de json_parse
  * @param char* La clef lié à la valeur
  * @return int constante JSON_XXXX du type de la valeur

+ 10 - 1
Serveur/main.c

@@ -6,6 +6,7 @@
 #include "server.h"
 #include "error.h"
 #include "bomberstudent_server.h"
+#include "client.h"
 
 /* --- Extern --- */
 extern Error error;
@@ -164,6 +165,11 @@ int serv_tcp(){
     return 0;
 }
 
+int handler(int cliId, JsonParser* jp){
+    printf("Handler : %d - %s\n", cliId, get_value(jp, "key"));
+    return 1;
+}
+
 int main(){
     //return parse();
     //return encode();
@@ -172,8 +178,10 @@ int main(){
     //return serv_udp();
     //return serv_tcp();
     
+    //*
     error_finit("bomberstudent_server.log");
     ini_server();
+    add_handler("POST", "aze/rty", handler);
     if(!launch_udp_server(PORT_UDP)){
         error.print("Impossible de démarrer le serveur");
         error.exit_err();
@@ -182,6 +190,7 @@ int main(){
         error.print("Impossible de démarrer le serveur");
         error.exit_err();
     }
-    sleep(30);
+    sleep(60);
     error.exit();
+    //*/
 }

+ 4 - 2
Serveur/makefile

@@ -3,7 +3,7 @@
 #
 
 EXEC = main
-OBJETS = str.o json_parser.o json_encoder.o error.o arraylist.o server_tcp.o server_udp.o bomberstudent_server.o
+OBJETS = str.o json_parser.o json_encoder.o error.o arraylist.o server_tcp.o server_udp.o bomberstudent_server.o client.o
 NOM_PROJET = Porjet Reseau
 
 #
@@ -103,4 +103,6 @@ server_tcp.o: server_tcp.c error.h server.h constante.h
 server_udp.o: server_udp.c error.h server.h constante.h
 bomberstudent_server.o: bomberstudent_server.c arraylist.h constante.h \
  server.h json.h str.h bomberstudent_server.h error.h
-main.o: main.c json.h str.h constante.h arraylist.h server.h error.h
+client.o: client.c client.h constante.h server.h
+main.o: main.c json.h str.h constante.h arraylist.h server.h error.h \
+ bomberstudent_server.h