Serveur apache en C

Impact -  
Hxyp Messages postés 401 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,


Dans le cadre de ma formation, je dois programmer un serveur HTTP en C (comm apache). Seulement, je reçois une erreur plus que déroutante. J'aimerais savoir s'il y a un moyen d'en savoir plus ou simplement de m'expliquer mon erreur.

Je pense que l'erreur vient de la création du thread. Cependant, je ne suis sûr de rien.

Je vous remercie d'avance et je suis prêt à vous donner tout renseignement complémentaire si besoin est


Le programme en C :

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <syslog.h>

char* notfound="404 NOT FOUND\0";
char *documentR;
char *log1;
char *serverR;
char *port;
char ip[INET_ADDRSTRLEN];

// Fonction qui est envoyée à un thread à chaque nouvelle connexion

void * connexion(void* desc4){
	int desc3;
	char chaine[1024],buffer[1024];
	char* recu, *page;
	char date[256];
	int taille,file,nb;

	
	desc3=*((int*)desc4);
	free(desc4);

  	taille=read(desc3,chaine,1024);
	strtok(chaine," ");
	recu=strtok(NULL," ");
	if(!strcmp(recu,"/"))
		recu="index.html\0";
	else{
		recu++;
	}
	
	// Ecrit la requête dans le fichier log
	
	//strftime(buffer, sizeof(buffer), "%c : ", localtime(time(NULL)));
	
	//printf("date : %s\n", date);
	
	page=malloc(sizeof(char)*strlen(documentR));
	strcpy(page,documentR);
	strcat(page,recu);

	file=open(page,O_RDONLY);
	if(file>0){
		while((nb=read(file,buffer,1024))>0){
			write(desc3,buffer,nb);
		}
	} else 
		write(desc3,notfound,strlen(notfound));
	close(file);

    	printf("Packet reçu : %s\n",page);

	close(desc3);
	pthread_exit(0);
}

void client_log(char *infos){
	int ficLog, tailleFic;
  	char bufferFic[1024];
	char * contenuFicConf=malloc(sizeof(char)*1025);
	char * contenuTmp="";

	// Ouverture du fichier de log à la fin du fichier
	
	ficLog=open("./log/logs_clients\0",O_APPEND);
	
	if(ficLog<=0){
		openlog("Server Apache:", LOG_PID, LOG_DAEMON);
		syslog(LOG_USER,"L'ouverture du fichier de logs clients a echoue.");
		closelog();
	}
	
	// Ecriture de la requête dans le fichier puis fermeture
	
	write(ficLog, infos, strlen(infos));
	close(ficLog);
}

int config(){
	int ficConf, tailleFic;
  	char bufferFic[1024];
	char * contenuFicConf=malloc(sizeof(char)*1025);
	char * contenuTmp="";

	// Ouverture et lecture du fichier de configuration
	
	ficConf=open("./serveur.conf\0",O_RDONLY);
	
	if(ficConf<=0){
		printf("AHJUUUUUUUUUUuu");
		return 1;
	}
	
	while((tailleFic=read(ficConf,bufferFic,1024))>0){
		contenuFicConf=malloc(sizeof(char)*(strlen(contenuTmp)+strlen(bufferFic)));
		strcat(contenuFicConf,contenuTmp);
		strcat(contenuFicConf,bufferFic);
		contenuTmp=contenuFicConf;
	}
	close(ficConf);

	// Séparation des fichiers

	documentR=strtok(contenuTmp,"\n");
	serverR=strtok(NULL,"\n");
	port=strtok(NULL,"\n");
	log1=strtok(NULL,"\n");

	strtok(documentR,"=");
	documentR=strtok(NULL,"");

	strtok(serverR,"=");
	serverR=strtok(NULL,"");

	strtok(port,"=");
	port=strtok(NULL,"");

	strtok(log1,"=");
	log1=strtok(NULL,"");

	return 0;
}

int main() {
	// On annonce au syslog que le serveur démarre
	openlog("Server Apache:", LOG_PID, LOG_DAEMON);
	syslog(LOG_NOTICE,"Le serveur pseudo-apache vient de demarrer.");
	closelog();
	
	/*
	chdir ("/");
	if( fork() != 0)
		exit(0) ;
	setsid() ;
	for (i=0; i<NOFILE ;i++)
		close(i);
	*/

	pthread_t tid;
	void *ret;
	int desc, desc2, taille, valeur=1, i=0;
	int desc4;
  	int longueur=sizeof(struct sockaddr_in);
	char * chaine;
  	struct sockaddr_in adr1,adr2;
  	
		printf("\n\n\n\n OMG \n\n\n\n");
	
	// Lecture du fichier de configuration
	
	if(config() > 0){
		openlog("Server Apache:", LOG_PID, LOG_DAEMON);
		syslog(LOG_EMERG,"L'ouverture du fichier de configuration a echoue.");
		closelog();
		exit(1);
	}


	
	// Ouverture du socket
	
	if((desc=socket(AF_INET,SOCK_STREAM,0)) == -1) {printf("miam\n");
		openlog("Server Apache:", LOG_PID, LOG_DAEMON);
		syslog(LOG_EMERG,"L'ouverture du socket est un échec.");
		closelog();
		exit(1);
	}
	else {
		if(setsockopt(desc, SOL_SOCKET, SO_REUSEADDR, &valeur, sizeof(valeur)) < 0){
			openlog("Server Apache:", LOG_PID, LOG_DAEMON);
			syslog(LOG_EMERG,"L'écriture du socket est un échec.");
			closelog();
			exit(1);
		}
	}

	adr1.sin_family=AF_INET;
	adr1.sin_addr.s_addr=htonl(INADDR_ANY);
	adr1.sin_port=htons(atoi(port));

	if(bind(desc,(struct sockaddr *)&adr1,longueur)==-1) {
		openlog("Server Apache:", LOG_PID, LOG_DAEMON);
		syslog(LOG_EMERG,"Le serveur n'a pas pu nommer la socket.");
		closelog();
		exit(1);
	}

	if(listen(desc,10)==-1) {
		openlog("Server Apache:", LOG_PID, LOG_DAEMON);
		syslog(LOG_EMERG,"Le serveur n'a pas pu ecoute le port.");
		closelog();
		exit(1);
	}

	do {
		if((desc2=accept(desc,(struct sockaddr *)&adr2,&longueur))==-1) {
			openlog("Server Apache:", LOG_PID, LOG_DAEMON);
			syslog(LOG_WARNING,"La requete d'un client n'a pu etre resolue.");
			closelog();
		} else {
			//desc4=malloc(sizeof(int));
			desc4=desc2;

			// Récupère l'adresse ip de l'utilisateur
			inet_ntop(AF_INET, &(adr2.sin_addr), ip, INET_ADDRSTRLEN);

			// Créer un nouveau thread par connexion
			
/* 
 *
 * JE PENSE QUE L'ERREUR VIENT DE LA CREATION DU THREAD 
 *
 */

			if(pthread_create(&tid,NULL,connexion, (void*)desc4)<0){
				openlog("Server Apache:", LOG_PID, LOG_DAEMON);
				syslog(LOG_WARNING,"La creation du thread est un echec.");
				closelog();
			}
		}
		
	} while(1); // while(1) ? Peut certainement être modifié ^^
	close(desc2);
	
	// On annonce au syslog que le serveur s'arrête
	openlog("Server Apache:", LOG_PID, LOG_DAEMON);
	syslog(LOG_NOTICE,"Le serveur pseudo-apache est en train de s'arrêter");
	closelog();

	exit(0);
} 





Le code d'erreur :

$ gcc -o serveur serveur.c -lpthread | ./serveur

*** glibc detected *** ./serveur: malloc(): memory corruption: 0x0a03e270 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6c501)[0xb7646501]
/lib/libc.so.6(+0x6f2fc)[0xb76492fc]
/lib/libc.so.6(__libc_calloc+0xb2)[0xb764a682]
/lib/ld-linux.so.2(_dl_allocate_tls+0x3c)[0xb77747cc]
/lib/libpthread.so.0(pthread_create+0x56a)[0xb773d6aa]
./serveur[0x8049245]
/lib/libc.so.6(__libc_start_main+0xe7)[0xb75f0ce7]
./serveur[0x8048921]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:07 3146806    /home/impact/Cours/Prog réseau/apache/serveur
0804a000-0804b000 r--p 00001000 08:07 3146806    /home/impact/Cours/Prog réseau/apache/serveur
0804b000-0804c000 rw-p 00002000 08:07 3146806    /home/impact/Cours/Prog réseau/apache/serveur
0a03c000-0a05d000 rw-p 00000000 00:00 0          [heap]
b6c00000-b6c21000 rw-p 00000000 00:00 0 
b6c21000-b6d00000 ---p 00000000 00:00 0 
b6dac000-b6dc6000 r-xp 00000000 08:07 5111887    /lib/libgcc_s.so.1
b6dc6000-b6dc7000 r--p 00019000 08:07 5111887    /lib/libgcc_s.so.1
b6dc7000-b6dc8000 rw-p 0001a000 08:07 5111887    /lib/libgcc_s.so.1
b6dd7000-b75da000 rw-p 00000000 00:00 0 
b75da000-b7731000 r-xp 00000000 08:07 5111902    /lib/libc-2.12.1.so
b7731000-b7733000 r--p 00157000 08:07 5111902    /lib/libc-2.12.1.so
b7733000-b7734000 rw-p 00159000 08:07 5111902    /lib/libc-2.12.1.so
b7734000-b7737000 rw-p 00000000 00:00 0 
b7737000-b774c000 r-xp 00000000 08:07 5112112    /lib/libpthread-2.12.1.so
b774c000-b774d000 ---p 00015000 08:07 5112112    /lib/libpthread-2.12.1.so
b774d000-b774e000 r--p 00015000 08:07 5112112    /lib/libpthread-2.12.1.so
b774e000-b774f000 rw-p 00016000 08:07 5112112    /lib/libpthread-2.12.1.so
b774f000-b7751000 rw-p 00000000 00:00 0 
b775f000-b7762000 rw-p 00000000 00:00 0 
b7762000-b7763000 r-xp 00000000 00:00 0          [vdso]
b7763000-b777f000 r-xp 00000000 08:07 5111870    /lib/ld-2.12.1.so
b777f000-b7780000 r--p 0001b000 08:07 5111870    /lib/ld-2.12.1.so
b7780000-b7781000 rw-p 0001c000 08:07 5111870    /lib/ld-2.12.1.so
bfd88000-bfda9000 rw-p 00000000 00:00 0          [stack]
Abandon
A voir également:

1 réponse

Hxyp Messages postés 401 Date d'inscription   Statut Membre Dernière intervention   54
 
Bonjour,
193 if(bind(desc,(struct sockaddr *)&adr1,longueur)==-1) {·
194 //openlog("Server Apache:", LOG_PID, LOG_DAEMON);·
195 //syslog(LOG_EMERG,"Le serveur n'a pas pu nommer la socket.");·
196 //closelog();·
197 exit(1);·
198 }·
Après avoir mis ces lignes en commentaire ça tourne et sort avec une erreur 01 (il n'y a plus de "malloc... thread... etc" erreur)

Edit: Au fait vous n'avez pas fourni le fichier "serveur.conf" ça n'aide pas des masses

Edit²: désolé en fait je n'étais pas en root pour ouvrir un port alors forcément..
dans connexion(void *desc4)
desc3=*((int*)desc4);
free(desc4);
il y a un problème avec le free enfin comme ça :
desc3=(int)desc4;
//free(desc4);
j'arrive à connecter deux clients sans erreurs il y a la création des threads, après pour l'envoie etc aucune idée. Edit 3: ouais non en fait ça fonctionne très bien, à testé :

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <string.h> 
#include <pthread.h> 
#include <syslog.h> 
#include <unistd.h> 

char* notfound="404 NOT FOUND\0"; 
char *documentR; 
char *log1; 
char *serverR; 
char *port; 
char ip[INET_ADDRSTRLEN]; 

  // Fonction qui est envoyée à un thread à chaque nouvelle connexion 

void * connexion(void* desc4){ 
    int desc3; 
    char chaine[1024],buffer[1024]; 
    char* recu, *page; 
    char date[256]; 
    int taille,file,nb; 

    desc3=(int)desc4; 
    //free(desc4); 

    taille=read(desc3,chaine,1024); 
  
    printf("%s\n",chaine); 

    close(desc3); 
    pthread_exit(0); 
} 

void client_log(char *infos){ 
    int ficLog, tailleFic; 
    char bufferFic[1024]; 
    char * contenuFicConf=malloc(sizeof(char)*1025); 
    char * contenuTmp=""; 

      // Ouverture du fichier de log à la fin du fichier 

    ficLog=open("./log/logs_clients\0",O_APPEND); 

    if(ficLog<=0){ 
        openlog("Server Apache:", LOG_PID, LOG_DAEMON); 
        syslog(LOG_USER,"L'ouverture du fichier de logs clients a echoue."); 
        closelog(); 
    } 

      // Ecriture de la requête dans le fichier puis fermeture 

    write(ficLog, infos, strlen(infos)); 
    close(ficLog); 
} 

int config(){ 
    int ficConf, tailleFic; 
    char bufferFic[1024]; 
    char * contenuFicConf=malloc(sizeof(char)*1025); 
    char * contenuTmp=""; 

      // Ouverture et lecture du fichier de configuration 

    ficConf=open("./serveur.conf\0",O_RDONLY); 

    if(ficConf<=0){ 
        printf("AHJUUUUUUUUUUuu"); 
        return 1; 
    } 

    while((tailleFic=read(ficConf,bufferFic,1024))>0){ 
        contenuFicConf=malloc(sizeof(char)*(strlen(contenuTmp)+strlen(bufferFic))); 
        strcat(contenuFicConf,contenuTmp); 
        strcat(contenuFicConf,bufferFic); 
        contenuTmp=contenuFicConf; 
    } 
    close(ficConf); 

      // Séparation des fichiers 

    documentR=strtok(contenuTmp,"\n"); 
    serverR=strtok(NULL,"\n"); 
    port=strtok(NULL,"\n"); 
    log1=strtok(NULL,"\n"); 

    strtok(documentR,"="); 
    documentR=strtok(NULL,""); 

    strtok(serverR,"="); 
    serverR=strtok(NULL,""); 

    strtok(port,"="); 
    port=strtok(NULL,""); 

    strtok(log1,"="); 
    log1=strtok(NULL,""); 

    return 0; 
} 
int main() { 
    printf("start\n"); 

    pthread_t tid; 
    void *ret; 
    int desc, desc2, taille, valeur=1, i=0; 
    int desc4; 
    int longueur=sizeof(struct sockaddr_in); 
    char * chaine; 
    struct sockaddr_in adr1,adr2; 

      // Lecture du fichier de configuration 

    if(config() > 0){ 
        printf("open configure fichier erreur\n"); 
        exit(1); 
    } 
      // Ouverture du socket 
    desc=socket(AF_INET,SOCK_STREAM,0); 
    if (desc!=-1){ 
        if(setsockopt(desc, SOL_SOCKET, SO_REUSEADDR, &valeur, sizeof(valeur)) < 0){ 
            printf("erreur setsockopt()\n"); 
            exit(1); 
        } 
    } 
    else printf("socket() erreur\n"); 

    adr1.sin_family=AF_INET; 
    adr1.sin_addr.s_addr=INADDR_ANY; 
      //adr1.sin_port=htons(atoi(port)); 
    adr1.sin_port=htons(80); 

    if(bind(desc,(struct sockaddr *)&adr1,sizeof(adr1))==-1) { 
        printf("erreur bind\n"); 
        exit(1); 
    } 

    if(listen(desc,10)==-1) { 
        printf("listen() erreur\n"); 
        exit(1); 
    } 

    do { 
        if((desc2=accept(desc,(struct sockaddr *)&adr2,&longueur))==-1) { 
            printf("accept() erreur\n"); 
        } else { 
              //desc4=malloc(sizeof(int)); 
            desc4=desc2; 

              // Récupère l'adresse ip de l'utilisateur 
            inet_ntop(AF_INET, &(adr2.sin_addr), ip, INET_ADDRSTRLEN); 

              // Créer un nouveau thread par connexion 

            if(pthread_create(&tid,NULL,connexion, (void*)desc4)<0){ 
                printf("pthread_create erreur\n"); 
            } 
        } 

    } while(1); // while(1) ? Peut certainement être modifié ^^ 
    close(desc2); 

    printf("arret du server\n"); 

    exit(0); 
} 
0