IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

probleme de gestion de clients avec des sockets....


Sujet :

Réseau C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2003
    Messages : 14
    Points : 10
    Points
    10
    Par défaut probleme de gestion de clients avec des sockets....
    hello tout le monde

    Je suis en train creer un serveur qui accepte un nombre limite de clients. De plus, (sa mission principale), il doit mettre le numero du socket client dans une structure(caracteristiques : no du socket, nom du client et un champs "points") afin de pouvoir differencier chaque client.

    Le probleme est que lorsque je veux afficher mes structures, elles n'existent pas (elles ne sont pas tjs pas initialisee) alors qu'elles le sont dans le processus fils.

    Apparement le probleme serait que lorsque je cree un nouveau socket, je dupplique alors le processus (avec le fork) ), donc tous mes clients inserent leur donnees dans la meme structure (joueur[0]), heuuu du moins c'est ce que je crois avoir compris de l'erreur.

    Si quelqu'un avait une idee de "comment faire pour bien initialiser les structures", et bien je lui serait vraiment tres reconnaissant :o


    Cela fait 2 jours que j'essaie de resoudre ce probleme sans succes


    Voici le code du serveur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    /* declaration des librairies */
     
     
    #define DEBUG_SERVER 1
     
     struct _joueur{
    	int id_j;
            char nom[50];
            int pts;
    };
     
    struct _joueur joueur[4];
     
    main(int argc, char *argv[]){
     
      /********declaration*********/
      int sock_rv; 			/*socket de rendez-vous */
      int socket_serv;		/*socket de service  */ 
      char buf[256];    			/* buffer*/
      struct sockaddr_in adr; 	/*structure d'une adresse (Sun) */
      struct sockaddr_in adresse;    
      int lgadr,lgadresse;		/* longueur de l'adresse*/
      struct hostent *hote;		/*infos sur l'hote*/
      char nomh[50];		/*nom de l'hote*/ 
      int nbJoueur=0;		/*Nombre de joueurs actuel */
     
      int i; 
      /****************************/
     
      /*creation de la socket de rendez-vous */
      if((sock_rv = socket(AF_INET, SOCK_STREAM, 0)) == -1){
    	perror("probleme avec la creation de la socket d'ecoute");
    	exit(1);
      }
     
      /* recuperation du nom de la machine presente */
      if (gethostname(nomh, 50) == -1) {
    	perror("pb dans le gethostbyname");
    	exit(1);
      }
     
     
      /* preparation de l'adresse locale : port + toutes les @ IP */
      adr.sin_family = AF_INET;
      adr.sin_port = htons(atoi(argv[1]));
      adr.sin_addr.s_addr = htonl(INADDR_ANY);
     
    /* attachement de la socket a l'adresse locale */
      lgadr = sizeof(adr);
      if ((bind(sock_rv, &adr, lgadr)) == -1) {
    	perror("bind"); 
    	exit(1);
      }
     
      /*Declaration du service d'ecoute */
      if(listen(sock_rv, 4)==-1){
    	perror("probleme avec le service d'ecoute");
    	exit(1);
      }
     
      /*boucle d'attente de connexion */ 
      while(nbJoueur++<4){
    	fflush(stdout);
     
    	lgadresse = sizeof(adresse);
    	socket_serv=accept(sock_rv, &adresse, &lgadresse);
    	if(socket_serv==-1 &&errno==EINTR)
    		continue;
     
    	if(socket_serv==-1){
    		perror("probleme lors de la creation socket_serv\n");
    		exit(1);
    	}
     
    	if(!fork()){
    		close(sock_rv);	
     
    		if(read(socket_serv, buf,sizeof(buf))==-1){
    			perror("probleme lors de la lecture");
    			exit(1);
    		}
     
    		 /*initialisation de la structure */
    		strcpy(joueur[nbJoueur].nom, buf);
    		joueur[nbJoueur].id_j=socket_serv;
    		joueur[nbJoueur].pts=0;
     
      		if(write(socket_serv, buf, sizeof(buf))==-1){
            		perror("pb lors de l'ecriture de la socket pour le serveur");
            		exit(1);
     
     
      		}  
    	close(socket_serv);
    	exit(0);
    	}
     
    }
     
      #if DEBUG_SERVER
    	printf("tableau de joueur\n");
    	printf("nbJoueur : %d\n", nbJoueur);
    	for(i=0; i<nbJoueur;i++){
    		printf("joueur %d\n\t id: %d \n\t nom : %s\n\t pts : %d\n",i,joueur[nbJoueur].id_j, joueur[nbJoueur].nom, joueur[nbJoueur].pts);	}
      #endif
      close(sock_rv);
    }


    Merci!

  2. #2
    Responsable technique

    Avatar de Anomaly
    Homme Profil pro
    Directeur
    Inscrit en
    Juin 2003
    Messages
    10 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Directeur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 333
    Points : 130 178
    Points
    130 178
    Billets dans le blog
    1
    Par défaut
    Je n'ai pas regardé ton code en détail, parce qu'il est bien long (enfin toi tu as pensé aux balises code, c'est pas le cas de tout le monde ).

    Mais le problème est que si tu utilises fork(), les variables ne sont pas partagées ! Elles sont dupliquées lors de la création du processus et après celles du père sont totalement indépendantes de celles du fils.

    La solution est de ne pas utiliser fork(), mais les threads (pthread_create), là, les variables globales sont partagées. Mais attention aux problèmes de concurrence (accès simultanées à la même variable).
    Responsable technique forum & site

    Si ce message (ou un autre) vous a aidé et/ou vous semble pertinent, votez pour lui avec

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2003
    Messages : 14
    Points : 10
    Points
    10
    Par défaut ok! Je vais tenter
    ok, merci Anomaly je vais essayer ca, mais je ne connais pas du tout les threads, y a t'il des choses a savoir avant de se lancer tout corps dedans?

    Je prefere demander ca car le suite du serveur va etre la suivante :

    1. Le serveur envoie une question
    2. Un client (joueur) doit repondre le plus rapidement possible en appuyant sur une touche (donc deja a la base il va y avoir du MUTEX pour eviter que 2 joueurs repondent a la meme question)....

    3. Puis on va passer a une autre etape du jeu, un peu a la question pour un champion...

    J'ai mis en place la structure du prog pour les sockets, mais je ne sais pas si cela peut changer pour les threads..

    Merci


    Ludo


    PS : Je vais enlever un peu de code pour le rendre plus digeste

  4. #4
    Responsable technique

    Avatar de Anomaly
    Homme Profil pro
    Directeur
    Inscrit en
    Juin 2003
    Messages
    10 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Directeur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 333
    Points : 130 178
    Points
    130 178
    Billets dans le blog
    1
    Par défaut
    Rien ne change normalement quand il y a des threads, mais il y a des petits choses à laquelle il faut faire attention :
    Certaines fonctions ne sont pas réeentrantes et ne doivent donc pas être appelées dans un contexte multithread - il existe des équivalents supportant le multithread. Exemple : localtime(), car il écrit sur une variable globale, équivalent sans risque : localtime_r().
    Les variables globales sont partagées. La mémoire allouée dynamiquement est partageable. Les variables locales ne sont pas partagées.
    Compile avec l'option -D_REENTRANT pour définir le symbole _REENTRANT. Cela change la définition de certains symboles pour devenir réentrant : le seul cas que je connais est errno, qui devient alors une fonction (invisible), gérant un code d'erreur par thread.
    Protège tout accès concurrentiel à une variable partagée dès que des accès en écriture sont possibles avec des mutex (fonctions de la famille pthread_mutex_lock()).
    Lie avec l'option -lpthread (sous Linux), -pthread (sous FreeBSD). Sous d'autres Unix la syntaxe peut être différente.
    Responsable technique forum & site

    Si ce message (ou un autre) vous a aidé et/ou vous semble pertinent, votez pour lui avec

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2003
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    Encore merci!

    C'est ce que j'appelle de judicieux conseils . Bon, et bien je sens que la nuit risque d'etre longue, il faut d'abord que je trouve de la doc sur les threads (et la difference avec un fork) .
    je te tiens (ainsi que les autres) au courant sur les modifications...

    ludo

  6. #6
    Membre habitué Avatar de Metal Tom
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 119
    Points : 129
    Points
    129
    Par défaut
    Si tu utilises les pthread (les POSIX quoi) tu as les mutex dans la même librairie : les pthread_mutex. C'est pas sompliqué à utilisé si tu est rigoureux.
    Tom

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2003
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    ok,

    En fait j'ai resolu le probleme sans les threads. C'etait juste un probleme tout bete : j'essayais de creer une structure lors de l'ouverture d'une socket... J'ai tout simplement creer un tableau de socket , et apres la creation de socket (lors tous les joueurs sont presents) je fais une demande de nom a chaque joueur grace au tableau de socket....

    Voila, il faut que j'arrete avec mon "pourquoi faire simple quand on peut faire compliquer".

    Merci tout le monde

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Client / serveur avec des sockets
    Par SASARITA dans le forum Réseau
    Réponses: 3
    Dernier message: 10/05/2014, 04h52
  2. Réponses: 18
    Dernier message: 28/03/2014, 11h28
  3. problème avec des sockets
    Par ddii dans le forum Réseau
    Réponses: 10
    Dernier message: 15/11/2005, 15h53
  4. Probleme avec des socket !
    Par Ptimath44 dans le forum Réseau
    Réponses: 11
    Dernier message: 31/10/2005, 18h11
  5. Réponses: 9
    Dernier message: 28/10/2005, 11h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo