From 28f538eb5295d8933589d13ee4a5cf32845b76d0 Mon Sep 17 00:00:00 2001 From: pfaure Date: Mon, 1 Mar 2021 19:49:26 +0100 Subject: [PATCH] Detection arret serveur OK --- client.c | 19 +++++-- serveur.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 156 insertions(+), 18 deletions(-) diff --git a/client.c b/client.c index ff91555..d88ba35 100644 --- a/client.c +++ b/client.c @@ -3,6 +3,7 @@ #include /* constantes relatives aux domaines, types et protocoles */ #include +#include /* constantes et structures propres au domaine INTERNET */ #include /* structures retournées par les fonctions de gestion de la base de @@ -55,6 +56,17 @@ int main (int argc, char * argv[]) { int cont = 1; while (cont) { + // Test si le serveur a crash + usleep(100000); + int oldflag = fcntl(sock, F_GETFL); + char buff2[40] = "\0"; + fcntl(sock, F_SETFL, oldflag | O_NONBLOCK); + if ((int)read(sock, buff2, 40) == 0) { + printf("\nSERVEUR KO\n\n"); + close(sock); + exit(-1); + } + fcntl(sock, F_SETFL, oldflag); // Lecture de la requette char requette[40]; @@ -65,15 +77,16 @@ int main (int argc, char * argv[]) { int param3 = -1; sscanf(requette, "%s %d %d %d", req, ¶m1, ¶m2, ¶m3); - + // Traitement de la requette char buff[40] = "\0"; + int nb_octets_envoyes; if (!strcmp(req, "READ")) { if (param1 < 0) { printf("ERROR SYNTAX\n"); } else { sprintf(buff, "r.%d.0.0", param1); - send(sock, buff, strlen(buff), 0); - + nb_octets_envoyes = send(sock, buff, strlen(buff), 0); + printf("nb_octets_envoyes = %d\n", nb_octets_envoyes); read(sock, buff, 40); printf("Tableau[%d] = %s\n", param1, buff); } diff --git a/serveur.c b/serveur.c index 103f32c..93ce290 100644 --- a/serveur.c +++ b/serveur.c @@ -14,6 +14,7 @@ /* pour le fork */ #include #include +#include /* pour la manipulation des strings */ #include @@ -26,11 +27,116 @@ // printf("BEFORE: %p\n", __builtin_return_address(0)); + +// +// DEBUT GESTION DES FILS +// + +struct proc { + int pid; + int sock; + struct proc * next; +}; + +struct proc_list { + int size; + struct proc * first; +}; + +struct proc_list new_list() { + struct proc_list liste = {0, NULL}; + return liste; +} + +void add_proc(struct proc_list * l, int pid, int sock) { + l->size++; + struct proc * p = (struct proc *) malloc(sizeof(struct proc)); + p->pid = pid; + p->sock = sock; + p->next = l->first; + l->first = p; +} + +int get_sock_and_remove_proc(struct proc_list * l, int pid) { + int sock = -1; + if (l->size == 0) { + printf("Erreur : Liste vide.\n"); + } else if (l->first->pid == pid) { + struct proc * aux = l->first; + l->size--; + l->first = aux->next; + sock = aux->sock; + free(aux); + } else { + struct proc * aux = l->first; + while (aux->next != NULL && aux->next->pid != pid) { + aux = aux->next; + } + if (aux->next->pid == pid) { + struct proc * aux2 = aux->next; + l->size--; + aux->next = aux2->next; + sock = aux2->sock; + free(aux2); + } + } + return sock; +} + +struct proc * get_first(struct proc_list * l) { + struct proc * rt = NULL; + if (l->size != 0) { + rt = l->first; + l->size--; + l->first = rt->next; + } + return rt; +} + +struct proc_list liste; + +// +// FIN GESTION DES FILS +// + +int main_sock; + void handle_sigsegv(int signum) { fprintf(stderr, "Signal SIGSEGV (%d) received : SEG FAULT\n", signum); _exit(0); } +void handle_sigchild(int signum) { + int pid = wait(NULL); + //printf("Processus %d terminé\n", pid); + int sock = get_sock_and_remove_proc(&liste, pid); + //printf("Retour shutdowm = %d\n", shutdown(sock, SHUT_RDWR)); + //printf("Retour close = %d\n", close(sock)); + shutdown(sock, SHUT_RDWR); + close(sock); +} + +void handle_sigint(int signum) { + // remove a handler for SIGCHLD in a part of your code + if (signal(SIGCHLD, NULL) == SIG_ERR) { + fprintf(stderr, "Could not install SIGSEGV handler"); + exit(-1); + } + + struct proc * rt = get_first(&liste); + while (rt != NULL) { + shutdown(rt->sock, SHUT_RDWR); + close(rt->sock); + kill(rt->pid, SIGINT); + free(rt); + rt = get_first(&liste); + //printf("ON DETRUIT TOUT\n"); + } + shutdown(main_sock, SHUT_RDWR); + close(main_sock); + exit(3); +} + int min(int a, int b) { if (a < b) { return a; @@ -139,6 +245,7 @@ void process(int sock) { } } } + int main(int argc, char *argv[]) { if (argc != 2) { @@ -152,9 +259,21 @@ int main(int argc, char *argv[]) { return -1; } + // install a handler for SIGCHLD in a part of your code + if (signal(SIGCHLD, &handle_sigchild) == SIG_ERR) { + fprintf(stderr, "Could not install SIGSEGV handler"); + return -1; + } + + // install a handler for SIGINT in a part of your code + if (signal(SIGINT, &handle_sigint) == SIG_ERR) { + fprintf(stderr, "Could not install SIGSEGV handler"); + return -1; + } + // On crée le socket local - int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == -1) { + main_sock = socket(AF_INET, SOCK_STREAM, 0); + if (main_sock == -1) { printf("ERREUR lors de la création du socket\n"); exit(1); } @@ -169,42 +288,48 @@ int main(int argc, char *argv[]) { // On bind l'adresse du socket créee avec le socket local binder = - bind(sock, (struct sockaddr *) &addr_local, sizeof(struct sockaddr_in)); + bind(main_sock, (struct sockaddr *) &addr_local, sizeof(struct sockaddr_in)); if (binder == -1) { printf("ERREUR lors du bind du socket\n"); exit(1); } // Initialisation file d'attente - listen(sock, 100); + listen(main_sock, 100); // Variable de stockage de l'addresse emmeteur struct sockaddr_in addr_em; unsigned int longueur_addr_em = sizeof(struct sockaddr_in); + // Initialisation de la liste des processus + liste = new_list(); + // On se met en état d'acceptation de connexion (et on crée un socket en // passant) int pid = 1; int nb_connexions = 0; + + printf("CTRL+C pour terminer\n"); while (pid != 0) { - int sock_connexion = - accept(sock, (struct sockaddr *) &addr_em, &longueur_addr_em); - nb_connexions++; + int sock_connexion = accept(main_sock, (struct sockaddr *) &addr_em, &longueur_addr_em); + if (sock_connexion == -1) { + printf("ERREUR lors de l'acceptation de la connexion\n"); + exit(1); + } else { + nb_connexions++; + } pid = fork(); if (pid == -1) { printf("ERREUR lors du fork\n"); exit(1); } else if (pid == 0) { - if (sock_connexion == -1) { - printf("ERREUR lors de l'acceptation de la connexion\n"); - exit(1); - } else { - // Traitement de la connexion - process(sock_connexion); - } + process(sock_connexion); + } else { + add_proc(&liste, pid, sock_connexion); + //printf("Processus %d created\n", pid); } } return 0; -} \ No newline at end of file +}