|
@@ -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);
|