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 :

Socket TCP: probleme avec select()


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut Socket TCP: probleme avec select()
    bonjour,

    en fait j'ai un petit problème avec les sockets en mode TCP...

    je programme un serveur multiclient, dans lequel, chaque client aura un traitement différent. J'utilise la fonction select().

    Le probleme, c'est que je ne sais pas à quel client j'ai affaire lorsque le serveur reçoit un message!
    Je voulais savoir si il y' a un moyen de reconnaitre quel client a envoyé le message?
    Je sais que select() utilise une file d'attente (où sont stockés les descripteurs de sockets connectés) et pointe le descripteur du client qui a envoyé un message, mais j'ignore comment accéder à ce champ.

    Si quelqu'un pouvait m'aider ça serait top. Merci

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par juve1897
    J'utilise la fonction select().

    Le probleme, c'est que je ne sais pas à quel client j'ai affaire lorsque le serveur reçoit un message!
    Je voulais savoir si il y' a un moyen de reconnaitre quel client a envoyé le message?
    Bah, il suffit d'utiliser select() correctement :

    http://emmanuel-delahaye.developpez....reseaux-c/#LVI

  3. #3
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    MErci pour ta réponse,

    cependant, j'ai déjà lu, la plupart des documents traitant de select(), mais je ne vois toujours pas comment faire.

    Je sais que FD_ISSET renvoie 1 si le descripteur de socket passé en paramètre est celui qui a envoyé le message. Mais moi, concrètement, comment pourrais je savoir dans quel ordre mes clients ont été enregistré dans la file ou encore quel est le descripteur qui leur est associé???

    Mon programme en fait est un jeu de morpion, où 2clients jouent...
    J'ai programmé des fonctions, parmis lesquelles se trouvent une qui se charge de rentrer la case jouée par l'un des clients dans le tableau.

    Mais pour savoir si je mets un "X" ou un "O" dans la case, il faut que je sache quel client a joué...

    Mais comment faire???

  4. #4
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par juve1897
    MErci pour ta réponse,

    cependant, j'ai déjà lu, la plupart des documents traitant de select(), mais je ne vois toujours pas comment faire.

    Je sais que FD_ISSET renvoie 1 si le descripteur de socket passé en paramètre est celui qui a envoyé le message. Mais moi, concrètement, comment pourrais je savoir dans quel ordre mes clients ont été enregistré dans la file ou encore quel est le descripteur qui leur est associé???

    Mon programme en fait est un jeu de morpion, où 2clients jouent...
    J'ai programmé des fonctions, parmis lesquelles se trouvent une qui se charge de rentrer la case jouée par l'un des clients dans le tableau.

    Mais pour savoir si je mets un "X" ou un "O" dans la case, il faut que je sache quel client a joué...

    Mais comment faire???
    Ben tu fais un tableau avec les sockets des clients. Ensuite tu parcours le tableau et tu fais le test avec la macro FD_ISSET

  5. #5
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Ca m'a l'aire d'etre une bonne idée, mais je vois pas comment faire.
    Est ce que tu purrais m'expliquer comment faire s'il te plait...

    si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for(desc_socket=3; desc_socket<taille_max_de_la_file; desc_socket++)
      if(FD_ISSET(desc_socket, file_d_attente))
       /* j'ajoute X dans mon tableau */
    Mais comment savoir si desc_sock represent mon client1 ou client2 ???

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par juve1897
    Mais comment savoir si desc_sock represent mon client1 ou client2 ???
    C'est à toi, au moment de la création du socket client (accept()), de créer le lien entre le socket du client et son identificateur dès que tu les connais...

    Une structure contenant le socket et l'identificateur est sans doute le plus simple....

    Si le nombre de client est limité, un simple tableau de structure permet de gérer tout ça. Si le socket vaut SOCKET_INVALID, la place est libre. A toi de bien gérer les déconnexions...

  7. #7
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Bonjour,

    j'ai reussit à resoudre les gros probleme, mon morpion marche mais seulement avec un serveur.
    Meme si j'en connecte 2, le serveur ,ne communique qu'avec un seul...

    je comprends pas pourquoi!!!

    Voilà le code du client, si quelqu'un pouvait me dire où est ce que ça coince, ça serait gentil.

    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
    #include "fonction.h"
     
    main(int argc, char *argv[])
    {
      int sock, rval;
     
      char *buf=malloc(sizeof(char)*1024);
      bzero(buf,sizeof(buf));
     
      char *data=malloc(sizeof(char)*1024);
      bzero(data,sizeof(data));
     
      struct sockaddr_in serveur_adr, sock_service;
      struct hostent *machine;
      int length;
     
      sock=socket (AF_INET, SOCK_STREAM, 0);
      if (sock < 0)
      {
        perror("socket client");
        exit(1);
      }
     
      bzero (&serveur_adr, sizeof (serveur_adr));
      serveur_adr.sin_family= AF_INET;
      serveur_adr.sin_port= htons(NPORT);
      serveur_adr.sin_addr.s_addr= inet_addr("127.0.0.1");
     
      if(connect(sock,(struct sockaddr*) &serveur_adr, sizeof(serveur_adr)) < 0)  //Connecte le client avec le serveur
      {
        perror("connect");
        close(sock);
        exit(1);
      }
     
      do
      {
        rval=read(sock,buf,1024);
     
        if( rval<0)
        {
          perror("read client");
          exit(1);
        }
        if(rval==0)
          printf("Fin de connection\n");
        else
        {
          msg_recu(buf);
          data=msg_saisi();
     
          if(write(sock, data, strlen(data)) < 0)  //Ecrit dans sock le nom du fichier
          {
            perror("write client");
            close(sock);
            exit(1);
          }
        }
      }while(rval!=0);//fin do while
      close (sock);
     
    }
    Merci.

  8. #8
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    J'ai pas compris ton problème.

    Si il marche avec un seul serveur ben c'est bon y'a pas besoin d'en mettre 2.
    Juste comme ça, tu peux pas avoir 2 serveur utilisant le même port sur une machine hein.

    A moins que tu voulais dire client.
    Réexplique ton problème stp.

    A propos de ton code :
    • malloc est inutile tu utilises une taille fixe
    • bzero est déprécié, utilise memset
    • le 1er argument de socket c'est PF_INET et non AF_INET
    • on écrit connexion et non connection

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Skyrunner
    • le 1er argument de socket c'est PF_INET et non AF_INET
    En fait, d'après POSIX.1, les deux sont confondus...

  10. #10
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    En fait, d'après POSIX.1, les deux sont confondus...
    Ah ben merci, je savais pas, je me suis fié au man.

    Au temps pour moi.

  11. #11
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    oui excuse moin je voulais dire client...

    Le serveur, ne communique qu'avec un seul des client, meme si j'en lance deux (chacun dans un terminal ,different biensur), le serveur, fait comme si il n'y'en avait qu'un seul.

    Je comprends pas pourquoi, j'ai bien fait un select dans le serveur...

    Et pour bzero(), le prof utilise cette fonction, donc je dois en faire de meme.

    Merci pour les corrections.

Discussions similaires

  1. probleme avec SELECT..FROM..WHERE
    Par VBBBA dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 08/09/2006, 15h58
  2. [EJB3][HIBERNATE] Probleme avec select max
    Par kristof_machin dans le forum Hibernate
    Réponses: 2
    Dernier message: 26/04/2006, 13h05
  3. [VB]probleme avec select case
    Par mickael99 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 03/02/2006, 14h07
  4. Probleme avec select
    Par sorry60 dans le forum Réseau
    Réponses: 20
    Dernier message: 16/12/2005, 17h23
  5. Probleme avec Select Case
    Par GeffD dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 07/03/2005, 15h28

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