Detection arret serveur OK

This commit is contained in:
Paul Faure 2021-03-01 19:49:26 +01:00
parent 13c05b02a3
commit 28f538eb52
2 changed files with 156 additions and 18 deletions

View file

@ -3,6 +3,7 @@
#include <sys/types.h>
/* constantes relatives aux domaines, types et protocoles */
#include <sys/socket.h>
#include <fcntl.h>
/* constantes et structures propres au domaine INTERNET */
#include <netinet/in.h>
/* 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, &param1, &param2, &param3);
// 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);
}

155
serveur.c
View file

@ -14,6 +14,7 @@
/* pour le fork */
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
/* pour la manipulation des strings */
#include <string.h>
@ -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;
}
}