Besoin d'aide dans la programmation des socket en c multiclient

Fermé
yasmine223 Messages postés 1 Date d'inscription mardi 22 janvier 2013 Statut Membre Dernière intervention 22 janvier 2013 - 22 janv. 2013 à 02:08
totof31 Messages postés 163 Date d'inscription lundi 29 octobre 2012 Statut Membre Dernière intervention 30 avril 2013 - 1 févr. 2013 à 11:36
Bonjour,
je veux realiser un programme de socket en c avec thread,a. lorsque le serveur reçoit un message d'un client, il le diffuse à tous les clients et attend l'arrivé d'autres messages.
j'essaye dans une premiere etape pour voir le fonctionnement de thread de connceter 3 client au serveur je veux seulement afficher les différents message des client
mais seulement le message d'un seul client s'affiche le serveur termine je sais pas est ce que j'ai un probleme dans pthread_join()
/*****************code serveur*****************************************
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netdb.h>
#include<netinet/in.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<pthread.h>
#define taille_max 20
static struct sockaddr_in addr_serveur;
static struct sockaddr_in addr_client;
int s_ecoute,s_service;
int lg_addr;
char *reponse="bien recu";
char *message[taille_max];
char *chaine_recue;
int nb_octet;
void *ma_fonction();

int main()
{
struct hostent *host_serveur;
host_serveur=gethostbyname("ubuntu");
bzero((char*)&addr_serveur,sizeof(addr_serveur));
//creation de la socket
s_ecoute=socket(AF_INET,SOCK_STREAM,0);
if(s_ecoute==-1)
{
perror("erreur de creation");
exit(1);
}
//remplir les champ se la structure
addr_serveur.sin_family=AF_INET;
addr_serveur.sin_port=htons(4000);
memcpy(&addr_serveur.sin_addr.s_addr,host_serveur->h_addr,host_serveur->h_length);///h_addr
//fct bind
if(bind(s_ecoute,(struct sockaddr *)&addr_serveur,sizeof(struct sockaddr_in))==-1)
{
perror("erreur de creation");
exit(1);
}
//fct listen
if(listen(s_ecoute,5)==-1)
{
perror("erreur d'ecoute");
exit(1);
}

int i=0;
//pthread_t thread2;
//pthread_t thread3;

//pthread_create(&thread2,NULL,&ma_fonction,NULL);
//pthread_create(&thread3,NULL,&ma_fonction,NULL);
//fct acceptation
lg_addr=sizeof(struct sockaddr_in);
pthread_t thread[3];
while(1){
s_service=accept(s_ecoute,(struct sockaddr *)&addr_client,&lg_addr);
if(s_service==-1)
{
perror("erreur d'acceptation");
exit(1);
}
//echange de msg


pthread_create( &(thread[i++]), NULL, ma_fonction, NULL );
sleep(10);

}
pthead_join(thread,NULL);


close(s_ecoute);
close(s_service);
EXIT_SUCCESS;
}
void *ma_fonction()
{
while(1){
nb_octet=read(s_service,message,taille_max);
chaine_recue=(char*)malloc(nb_octet * sizeof(char));
memcpy(chaine_recue,message,nb_octet);
printf("le client me dit :%s\n",chaine_recue);
nb_octet=write(s_service,reponse,strlen(reponse)+1);
}
}
/****************code de client**************************************
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#define taille_max 20
int main(int argc,char *argv[])
{
static struct sockaddr_in addr_serveur;
int s_id;
char *message="bonjour serveur2";
char reponse[taille_max];
int nb_octet;
//identification de la machine
struct hostent *host_serveur;
host_serveur=gethostbyname("ubuntu");
bzero((char*)&addr_serveur,sizeof(addr_serveur));
//1-creation de socket
s_id=socket(AF_INET,SOCK_STREAM,0);
if(s_id==-1)
{
perror("erreur de creation");
exit(1);
}
//remplir la socket
addr_serveur.sin_family=AF_INET;
addr_serveur.sin_port=htons(4000);
memcpy(&addr_serveur.sin_addr.s_addr,host_serveur->h_addr,host_serveur->h_length);///h_addr
//connection au serveur
if(connect(s_id,(struct sockaddr*)&addr_serveur,sizeof(addr_serveur))==-1)
{
perror("erreur de connexion");
exit(1);
}
///echange de message
nb_octet=write(s_id,message,strlen(message)+1);
nb_octet=read(s_id,reponse,taille_max);
printf("le serveur dit :%s\n",reponse);
close(s_id);
}
le meme code pour les 2autres cleint seulement le contenu de message qui change
merci
A voir également:

1 réponse

totof31 Messages postés 163 Date d'inscription lundi 29 octobre 2012 Statut Membre Dernière intervention 30 avril 2013 74
Modifié par totof31 le 1/02/2013 à 11:36
Bonjour,

Ton erreur vient du fait qu'à chaque fois que tu passes par accept, tu reçois un nouveau descripteur de socket. Or tu ne mémorises que le dernier avec s_service. Il faut tous les mémoriser (dans un tableau par exemple).

Ensuite, quand tu crées ton thread, il faut lui passer le nouveau descripteur pour qu'il écoute (read) uniquement sur celui-ci.

Enfin, lors de l'envoi vers les clients connectés, il faut faire autant de write qu'il y a de client (boucle avec les éléments du tableau des descripteurs), sauf peut-être pour le client qui a émis le message.
0