From dcda721939bc81c58f66850aa21f6b6f0c64cab3 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 23 Jan 2011 14:36:05 +0000 Subject: Refactoring : myhttpd -> tcpserver et process -> dispatcher. Faisaons de belles briques bien claires d'entrée de jeu ! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2011-usi/trunk@15 db941bf7-0cb3-4dda-9634-87faf64f93a7 --- app/v3_c/src/CMakeLists.txt | 8 +-- app/v3_c/src/dispatcher.c | 33 +++++++++++ app/v3_c/src/include/dispatcher.h | 13 +++++ app/v3_c/src/include/process.h | 13 ----- app/v3_c/src/main.c | 9 +++ app/v3_c/src/myhttpd.c | 118 -------------------------------------- app/v3_c/src/process.c | 33 ----------- app/v3_c/src/tcpserver.c | 118 ++++++++++++++++++++++++++++++++++++++ app/v3_c/src/tcpserver.h.in | 10 ++++ 9 files changed, 187 insertions(+), 168 deletions(-) create mode 100644 app/v3_c/src/dispatcher.c create mode 100644 app/v3_c/src/include/dispatcher.h delete mode 100644 app/v3_c/src/include/process.h create mode 100644 app/v3_c/src/main.c delete mode 100644 app/v3_c/src/myhttpd.c delete mode 100644 app/v3_c/src/process.c create mode 100644 app/v3_c/src/tcpserver.c create mode 100644 app/v3_c/src/tcpserver.h.in diff --git a/app/v3_c/src/CMakeLists.txt b/app/v3_c/src/CMakeLists.txt index 4a85291..7953490 100644 --- a/app/v3_c/src/CMakeLists.txt +++ b/app/v3_c/src/CMakeLists.txt @@ -3,10 +3,10 @@ set(SRC_COMMON utils.c) # configure a header file to pass some of the CMake settings # to the source code configure_file ( - "myhttpd.h.in" - "${PROJECT_BINARY_DIR}/myhttpd.h" + "tcpserver.h.in" + "${PROJECT_BINARY_DIR}/tcpserver.h" ) -add_executable(myhttpd myhttpd.c process.c ${SRC_COMMON} ) -#target_link_libraries(netlem SDL SDL_net SDL_image) +add_executable(usi2011jjl main.c tcpserver.c dispatcher.c ${SRC_COMMON} ) +#target_link_libraries(usi2011jjl SDL SDL_net SDL_image) diff --git a/app/v3_c/src/dispatcher.c b/app/v3_c/src/dispatcher.c new file mode 100644 index 0000000..84b1fda --- /dev/null +++ b/app/v3_c/src/dispatcher.c @@ -0,0 +1,33 @@ +#include +#include + +#include "dispatcher.h" +#include "utils.h" + +int initDispatcher() { + // Créer au départ toutes les zones mémoire à gérer + pool de threads + files de sockets en attente... + // Utiliser des déclarations globales dans ce fichier et gérer la concurrence entre les threads + + return 0; +} + +// Appelé des qu'un nouveau socket client est créé via accept(). +// Un retour non nul de cette fonction provoque l'arrêt du serveur http +int requestDispatcher(int sockfd, struct sockaddr_in *addr, socklen_t *addrlen ) { +#ifdef HEAVYDEBUG + logs("requestDispatcher start"); +#endif + if ( 0 ) { printf("%i %p %p\n", sockfd, (void *)addr, (void *)addrlen); } + + + close(sockfd); +#ifdef HEAVYDEBUG + logs("requestDispatcher end"); +#endif + return 0; +} + +void freeDispatcher() { + // Libérer tous les espaces histoire de voir des infos propres dans valgrind + return; +} diff --git a/app/v3_c/src/include/dispatcher.h b/app/v3_c/src/include/dispatcher.h new file mode 100644 index 0000000..a3e779a --- /dev/null +++ b/app/v3_c/src/include/dispatcher.h @@ -0,0 +1,13 @@ +#ifndef DISPATCHER_H +#define DISPATCHER_H + +#include +#include +#include +#include + +int initDispatcher(); +int requestDispatcher(int sockfd, struct sockaddr_in *addr, socklen_t *addrlen ); +void freeDispatcher(); + +#endif diff --git a/app/v3_c/src/include/process.h b/app/v3_c/src/include/process.h deleted file mode 100644 index c88b235..0000000 --- a/app/v3_c/src/include/process.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PROCESS_H -#define PROCESS_H - -#include -#include -#include -#include - -int initProcess(); -int requestProcess(int sockfd, struct sockaddr_in *addr, socklen_t *addrlen ); -void freeProcess(); - -#endif diff --git a/app/v3_c/src/main.c b/app/v3_c/src/main.c new file mode 100644 index 0000000..c88485e --- /dev/null +++ b/app/v3_c/src/main.c @@ -0,0 +1,9 @@ +#include "tcpserver.h" + +#define USI2011JJL_VERSION_MAJOR @USI2011JJL_VERSION_MAJOR@ +#define USI2011JJL_VERSION_MINOR @USI2011JJL_VERSION_MINOR@ + + +int main() { + return tcpserver(); +} diff --git a/app/v3_c/src/myhttpd.c b/app/v3_c/src/myhttpd.c deleted file mode 100644 index 9d77949..0000000 --- a/app/v3_c/src/myhttpd.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "myhttpd.h" -#include "process.h" -#include "utils.h" - -int end=0; - -void signals(int signum) { - static int force=0; - - if (0) printf("signal %i\n"); - - if(!force) { - end=1; - force=1; - logs("Tentative d'arrêt soft du serveur..."); - } else { - logs("Arrêt d'urgence du serveur"); - exit(1); - } -} - - -int main() { - int res; - int sockServ, sockCli; - struct sockaddr_in servAddr, cliAddr; - socklen_t cliAddrLen; - - // Création socket - sockServ = socket(AF_INET, SOCK_STREAM, 0); - if (sockServ < 0) { perror("socket"); return(2); } - - // Accrochage du socket (adresse et port locaux) - bzero((char *) &servAddr, sizeof(servAddr)); - servAddr.sin_family = AF_INET; - servAddr.sin_addr.s_addr = INADDR_ANY; - servAddr.sin_port = htons(LISTEN_PORT); - res=bind(sockServ, (struct sockaddr *) &servAddr, sizeof(servAddr)); - if (res < 0) { perror("bind"); return(3); } - - // On lance l'écoute - listen(sockServ,LISTEN_BACKLOG); - if (res < 0) { perror("listen"); return(4); } - - // On active la gestion des signaux - signal(2,signals); - - res=initProcess(); - if (res != 0 ) { -#ifdef DEBUG - logs("initProcess() error"); -#endif - return(5); - } - - // Boucle d'acceptation des clients - cliAddrLen = sizeof(cliAddr); - while ( ! end ) { - // Appel bloquant d'acceptation d'un nouveau client - sockCli=accept(sockServ, (struct sockaddr *) &cliAddr, &cliAddrLen); - - // Il y plein de raisons pour qu'un accept echoue - if (sockCli < 0) { - switch(errno) { - case EAGAIN: - case EINTR: - // Cas qui ne sont pas des erreurs, mais nécessitent de rappeler accept -#ifdef DEBUG - perror("accept (info)"); -#endif - break; - case EMFILE: - case ENFILE: - case ENOBUFS: - case ENOMEM: - // Cas d'erreur transitoire (attente d'une seconde histoire d'attendre un peu si ressources fichiers, ram épuisés -#ifdef DEBUG - perror("accept (warn)"); - sleep(1); -#endif - break; - default: - // Cas d'erreur fatales - perror("accept (err)"); - end=2; - } - } else { - // Cas nominal : un nouveau socket est disponible avec un client au bout -#ifdef HEAVYDEBUG - logs("Client accepté"); -#endif - end=requestProcess(sockCli, &cliAddr, &cliAddrLen); - } - } - - freeProcess(); - - if ( end != 1 ) { -#ifdef DEBUG - logs("Fin anormale du serveur"); -#endif - return(6); - } - - return 0; -} - diff --git a/app/v3_c/src/process.c b/app/v3_c/src/process.c deleted file mode 100644 index 630c718..0000000 --- a/app/v3_c/src/process.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "process.h" -#include "utils.h" - -int initProcess() { - // Créer au départ toutes les zones mémoire à gérer + pool de threads + files de sockets en attente... - // Utiliser des déclarations globales dans ce fichier et gérer la concurrence entre les threads - - return 0; -} - -// Appelé des qu'un nouveau socket client est créé via accept(). -// Un retour non nul de cette fonction provoque l'arrêt du serveur http -int requestProcess(int sockfd, struct sockaddr_in *addr, socklen_t *addrlen ) { -#ifdef HEAVYDEBUG - logs("requestProcess start"); -#endif - if ( 0 ) { printf("%i %p %p\n", sockfd, (void *)addr, (void *)addrlen); } - - - close(sockfd); -#ifdef HEAVYDEBUG - logs("requestProcess end"); -#endif - return 0; -} - -void freeProcess() { - // Libérer tous les espaces histoire de voir des infos propres dans valgrind - return; -} diff --git a/app/v3_c/src/tcpserver.c b/app/v3_c/src/tcpserver.c new file mode 100644 index 0000000..53b86a9 --- /dev/null +++ b/app/v3_c/src/tcpserver.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tcpserver.h" +#include "dispatcher.h" + +int end=0; + +void _signals(int signum) { + static int force=0; + + if (0) printf("signal %i\n", signum); + + if(!force) { + end=1; + force=1; + logs("Tentative d'arrêt soft du serveur..."); + } else { + logs("Arrêt d'urgence du serveur"); + exit(1); + } +} + + +int tcpserver() { + int res; + int sockServ, sockCli; + struct sockaddr_in servAddr, cliAddr; + socklen_t cliAddrLen; + + // Création socket + sockServ = socket(AF_INET, SOCK_STREAM, 0); + if (sockServ < 0) { perror("socket"); return(2); } + + // Accrochage du socket (adresse et port locaux) + bzero((char *) &servAddr, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = INADDR_ANY; + servAddr.sin_port = htons(LISTEN_PORT); + res=bind(sockServ, (struct sockaddr *) &servAddr, sizeof(servAddr)); + if (res < 0) { perror("bind"); return(3); } + + // On lance l'écoute + listen(sockServ,LISTEN_BACKLOG); + if (res < 0) { perror("listen"); return(4); } + + // On active la gestion des signaux + signal(2,_signals); + + res=initDispatcher(); + if (res != 0 ) { +#ifdef DEBUG + logs("initDispatcher() error"); +#endif + return(5); + } + + // Boucle d'acceptation des clients + cliAddrLen = sizeof(cliAddr); + while ( ! end ) { + // Appel bloquant d'acceptation d'un nouveau client + sockCli=accept(sockServ, (struct sockaddr *) &cliAddr, &cliAddrLen); + + // Il y plein de raisons pour qu'un accept echoue + if (sockCli < 0) { + switch(errno) { + case EAGAIN: + case EINTR: + // Cas qui ne sont pas des erreurs, mais nécessitent de rappeler accept +#ifdef DEBUG + perror("accept (info)"); +#endif + break; + case EMFILE: + case ENFILE: + case ENOBUFS: + case ENOMEM: + // Cas d'erreur transitoire (attente d'une seconde histoire d'attendre un peu si ressources fichiers, ram épuisés +#ifdef DEBUG + perror("accept (warn)"); + sleep(1); +#endif + break; + default: + // Cas d'erreur fatales + perror("accept (err)"); + end=2; + } + } else { + // Cas nominal : un nouveau socket est disponible avec un client au bout +#ifdef HEAVYDEBUG + logs("Client accepté"); +#endif + end=requestDispatcher(sockCli, &cliAddr, &cliAddrLen); + } + } + + freeDispatcher(); + + if ( end != 1 ) { +#ifdef DEBUG + logs("Fin anormale du serveur"); +#endif + return(6); + } + + return 0; +} + diff --git a/app/v3_c/src/tcpserver.h.in b/app/v3_c/src/tcpserver.h.in new file mode 100644 index 0000000..14b6736 --- /dev/null +++ b/app/v3_c/src/tcpserver.h.in @@ -0,0 +1,10 @@ +#ifndef TCPSERVER_H +#define TCPSERVER_H + +#define LISTEN_PORT 8080 +#define LISTEN_BACKLOG 5 + +int tcpserver(); + +#endif + -- cgit v1.2.3