Detection arret serveur OK
This commit is contained in:
parent
13c05b02a3
commit
28f538eb52
2 changed files with 156 additions and 18 deletions
19
client.c
19
client.c
|
@ -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, ¶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);
|
||||
}
|
||||
|
|
155
serveur.c
155
serveur.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue