Client/Serveur avec thread sous linux

frater_sinister Messages postés 4 Date d'inscription dimanche 18 janvier 2004 Statut Membre Dernière intervention 4 janvier 2007 - 18 janv. 2004 à 17:08
cs_fll Messages postés 15 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 20 septembre 2004 - 24 févr. 2004 à 10:57
J'ai un prblm avec ce programme. Avant tout le but de ce code: le client envoit un fichier au serveur, ce dernier renvoit le nombre de lignes/mots/lettres dans le fichier. Le prblm se situe au niveau des thread je pense. Dès la première connexion, le serveur créé un thread et effectue son calcul et des que le thread quitte, la fonction se termine alors qu elle devrai rester grace à la boucle infinie en attente de nouveaux clients.

Code serveur:
// serveur.c

#include<stdio.h>
#include<stdlib.h>
#include
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include

pthread_t thread;
pthread_attr_t attr;

struct sockaddr_in addr_c,addr_s,temp;

void *countLine(int sock_service) {
char c, buf[100];
int nb_mots = 0;
int nb_lignes = 0;
int nb_lettres = 0;

while(read(sock_service,&c,1) == 1){
if((c== '\\t')||(c==' '))
nb_mots++;
if(c=='\\n')
nb_lignes++;
else
nb_lettres++;
}
sprintf(buf,"ligne %d, mots %d, lettres = %d\\n",nb_lignes,nb_mots,nb_lettres);
//printf("%s",buf);
write(sock_service,buf,strlen(buf));

pthread_exit(NULL);
}

int main(int argc,char** argv){
int port, ecoute, connexion;
int lg_adr = sizeof(struct sockaddr_in);
int sock,sock_service,x;
char c;

/* on teste le nombre d'argument */
if(argc != 2){
perror("le nombre d'argument de %s doit etre egal a 2\\n");
exit(1);
}

//if (fork() != 0) exit(0); //démon
//setsid(); //session

/* création et attachement de la socket d'ecoute */

if( (sock = socket(AF_INET,SOCK_STREAM,0) ) <0 ){
perror("erreur creation de socket\\n");
exit(2);
}

addr_s.sin_port = htons(atoi(argv[1]));
addr_s.sin_addr.s_addr = htonl(INADDR_ANY);
addr_s.sin_family = AF_INET;
if( bind(sock,(struct sockaddr*)&addr_s,sizeof(struct sockaddr_in)) != 0){
perror("erreur bind()\\n");
exit(3);
}

/* on accepte une seule connexion */
listen(sock,5);

for(;;){
/* attente de connexion d'un client */
sock_service = accept(sock,(struct sockaddr*)&addr_c,&x);
/* Affichage des informations sur le client*/
printf("un client connecté en local sur le port %d\\n",ntohs(addr_c.sin_port) );

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

if((pthread_create(&thread,&attr,countLine(sock_service),NULL)) != 0)
break;
close(sock_service);
}

close(sock);
return(0);
}

Code client:

#include<stdio.h>
#include<stdlib.h>
#include
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>

int main(int argc,char** argv){
FILE *f;
char *buf, buf2;
int nb_caractere, i;
struct hostent *hp;
struct sockaddr_in addr_c,addr_s,temp;
int sock,x;

if(argc != 4){
perror("le nombre d'argument de %s doit etre egal a 2\\n");
exit(1);
}

/* Creation socket client */
if( (sock = socket(AF_INET,SOCK_STREAM,0) ) <0 ){
perror("erreur creation de socket\\n");
exit(2);
}

/* Attachement socket client */
addr_c.sin_port = htons(0);
addr_c.sin_family = AF_INET;
addr_c.sin_addr.s_addr = htonl(INADDR_ANY);
if( bind(sock,(struct sockaddr*)&addr_c,sizeof(struct sockaddr_in)) != 0){
perror("erreur bind()\\n");
exit(3);
}

/* Recuperation d'information sur le client*/
getsockname(sock,(struct sockaddr*)&temp,&x);
printf("client sur le port %d \\n",ntohs(temp.sin_port) );

/* Recuperation des informations sur le serveur */
hp = gethostbyname(argv[1]);
addr_s.sin_port = htons(atoi(argv[2]));
bcopy( (char*)hp->h_addr, (char*)&addr_s.sin_addr.s_addr, hp->h_length);

addr_s.sin_family = AF_INET;

printf("nom officiel du serveur %s\\n",hp->h_name);

/* connection au serveur */

connect(sock,(struct sockaddr*)&addr_s,sizeof(struct sockaddr_in));
if((buf (char *) calloc(256, sizeof(char))) NULL)
perror("erreur d'allocation memoire\\n");

/* envoie du message au serveur */
f = fopen(argv[3],"r");

while((nb_caractere = fread(buf,1,256,f))!= 0)
write(sock,buf,nb_caractere);

if(shutdown(sock, SHUT_WR) == -1)
perror("shutdown en ecriture");

while(read(sock,&buf2,1) == 1){
printf("%c",buf2);
}
printf("\\n");

fclose(f);
close(sock);

return 0;
}

Merci beaucoup à ceux qui prennent un peu de leur temps pour m'aider

1 réponse

cs_fll Messages postés 15 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 20 septembre 2004
24 févr. 2004 à 10:57
Salut !

Je suppose que ton client ne doit pas recevoir grand chose comme réponse. Si oui, alors c'est que tu as de la chance.

Dans les lignes suivantes, tu crées ton thread et tu le détruis immédiatement !!!

if((pthread_create(&thread,&attr,countLine
(sock_service),NULL)) != 0)
break;
close(sock_service);

Ton serveur se plante parce que tu essaies de lire/écrire sur un socket qui n'est plus valide.
Explication :
Tu devrais détruire ton socket à la sortie du thread (après avoir reçu un accusé de réception de ton client, sonon plantage du client).
0
Rejoignez-nous