Serveur apache en C
Impact
-
Hxyp Messages postés 401 Date d'inscription Statut Membre Dernière intervention -
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 :
Le code d'erreur :
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:
- Serveur apache en C
- Changer serveur dns - Guide
- Apache open office gratuit - Télécharger - Suite bureautique
- Serveur dns gratuit - Guide
- Serveur entrant et sortant - Guide
- Serveur dns orange - Accueil - Guide box et connexion Internet
1 réponse
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é :
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);
}