main.c 3.16 KB
#include <stdio.h>
#include <stdlib.h> // pour exit()
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netdb.h>

#define BUFFER_SIZE 1000
#define MAX_TCP_CONNEXION 5

// Fonction permettant de créer le serveur TCP
// service est le numéro ou nom de port (ex: "80" ou "http")
int initialisationServeurTCP(char *service){
    struct addrinfo precisions, *resultat, *origine;
    int statut;
    int s;

    /* Construction de la structure adresse */
    memset(&precisions, 0, sizeof precisions);
    precisions.ai_family = AF_UNSPEC;
    precisions.ai_socktype = SOCK_STREAM;
    precisions.ai_flags = AI_PASSIVE;
    statut = getaddrinfo(NULL, service, &precisions, &origine);
    if(statut < 0){ 
        perror("initialisationSocketTCP.getaddrinfo");
        exit(EXIT_FAILURE); 
    }
    struct addrinfo *p;
    for(p = origine, resultat = origine; p != NULL; p = p->ai_next) {
        if(p->ai_family == AF_INET6){ 
            resultat = p; 
            break;
        }
    }

    /* Creation d'une socket */
    s = socket(resultat->ai_family, resultat->ai_socktype, resultat->ai_protocol);
    if(s < 0){
        perror("initialisationSocketTCP.socket");
        exit(EXIT_FAILURE);
    }

    /* Options utiles */
    int vrai = 1;
    if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &vrai, sizeof(vrai))<0) {
        perror("initialisationServeurTCPgenerique.setsockopt (REUSEADDR)");
        exit(-1);
    }

    /* Specification de l'adresse de la socket */
    statut = bind(s, resultat->ai_addr, resultat->ai_addrlen);
    if(statut<0) {
        perror("initialisationServeurTCP.bind");
        exit(-1);
    }

    /* Liberation de la structure d'informations */
    freeaddrinfo(origine);

    /* Taille de la queue d'attente */
    statut = listen(s, MAX_TCP_CONNEXION);
    if(statut < 0)
        return -1;
    return s;
}

// Accepte toutes les connexions au serveur TCP et execute la fonction en argument
// ATTENTION : non multi-threadé ! -> il faut un pthread_create dans traitement pour le multi-thread.
int boucleServeurTCP(int socket, void (*traitement)(int)){
    while(1){
	    // accept connection
        struct sockaddr ip_src;
        socklen_t ip_len = sizeof(struct sockaddr);
        int socket_dialogue = accept(socket, &ip_src, &ip_len);
        if(socket_dialogue < 0){
            perror("boucleServeur.accept");
            return -1;
        }

	    // callback function
        traitement(socket_dialogue);
    }
    return 0;
}

void exemple_traitement(int socket){
    FILE *dialogue = fdopen(socket, "a+");
    if(dialogue==NULL){ perror("gestionClientHTTP.fdopen"); exit(-1); }
    
    char line[BUFFER_SIZE];
    char *success = fgets(line, BUFFER_SIZE, dialogue);
    if(success == NULL){
        fclose(dialogue);
        return;
    }
    
    printf("Message recu :\n\n%s\n", line);
    fprintf(dialogue, "Message recu :\n\n%s\n", line);
    
    fclose(dialogue);
}

int main(void){
    // init serveur
    char service[50] = "2030";
    int socket = initialisationServeurTCP(service);

    // lancement boucle infinie
    boucleServeurTCP(socket, exemple_traitement);

    return 0;
}