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

 C Discussion :

Utilisation de Select() avec deux sockets ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 15
    Par défaut Utilisation de Select() avec deux sockets ?
    Bonjour,

    je cherche comment utiliser la fonction select pour attendre un événement sur deux sockets ( exemple : un programme proxy qui ouvre un socket client et un socket serveur et attend un événement de l'un des deux) .

    voila ma boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    while (1)
    {
              FD_ZERO(&readfs);
              FD_SET(sock_client, &readfs);
              FD_SET(sock_serveur, &readfs);
     
          if(select(sock, &readfs, NULL, NULL, NULL) < 0)
    ...
    ...
    ...
    }
    Je ne sais pas comment gérer les deux socket dans "sock" 1er argument de select ?
    Merci de votre aide .

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    sock doit être le plus grand des deux file descriptors, plus 1 :
    nfds is the highest-numbered file descriptor in any of the three sets,
    plus 1.

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 15
    Par défaut
    OK, j'ai modifié un peu mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    .....
    max = client_sock > serveur_sock ? client_sock : serveur_sock;
    select(max + 1, &readfs, NULL, NULL, NULL) 
     
    if(FD_ISSET(max, &readfs))
    {
    recv(max, buffer, sizeof(buffer), 0);
      if (max== client_sock)
                         send(serveur_sock, buffer, strlen(buffer), 0); 
                      else
                          send(client_sock, buffer, strlen(buffer), 0);
    }
    Problème :
    Comme le client se connecte au proxy avant le serveur au début de mon code, (serveur_sock > client_sock) => la communication n'est possible que entre le proxy et le serveur le proxy ne peut pas recevoir les message du client !!
    Merci.

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2011
    Messages : 19
    Par défaut
    En fait, il faut que tu testes tes deux sockets avec FD_ISSET et pas seulement max (qui est ton en fait serveur_sock dans ton cas).

    Sur le principe du select, il faut donner à select() le descripteur le plus haut + 1, mais après il faut tester chaque descripteurs.

    Tu devrais avoir qqch comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select(max + 1, &readfs, NULL, NULL, NULL) 
    if(FD_ISSET(client_sock, &readfs))
    {
    ...
    }
    if(FD_ISSET(serveur_sock, &readfs))
    {
    ...
    }

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Par défaut
    Ce cours peut t'être très utile.

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 15
    Par défaut
    Merci mercyril pour ta réponse :

    En fait, il faut que tu testes tes deux sockets avec FD_ISSET et pas seulement max (qui est ton en fait serveur_sock dans ton cas).
    Mon code fonctionne bien maintenant :

    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
     
    select(max + 1, &readfs, NULL, NULL, NULL) 
    if(FD_ISSET(client_sock, &readfs))
    {
    ...
    /*receive from client */
    /* send to server */
    }
     
    if(FD_ISSET(serveur_sock, &readfs))
    {
    ...
    /*receive from server */
    /* send to client */
    ...
    }
    Merci matafan et Obsidian pour les explications
    super forum

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Hello,

    Citation Envoyé par sernos Voir le message
    Problème :
    Comme le client se connecte au proxy avant le serveur au début de mon code,
    Doit-on en déduire que le code que tu nous présentes est celui d'un proxy que tu es en train d'écrire ? Pour l'instant, rien ne nous permet en l'état de savoir où tu veux en venir.

    (serveur_sock > client_sock) => la communication n'est possible que entre le proxy et le serveur le proxy ne peut pas recevoir les message du client !!
    Non, cela n'a rien à voir. Les valeurs contenues par « serveur_sock » et « client_sock » sont des descripteurs de fichiers. Le fait de passer « sock+1 » à select() permet simplement de lui indiquer le plus grand numéro de descripteur à surveiller, ce qui lui permet en interne de dimensionner correctement ses tableaux pour faire sa gestion et, accessoirement, de savoir où s'arrêter.

    Si ton proxy se connecte à ton serveur, puis qu'il attend la connexion d'un client et qu'il gère ensuite les deux en parallèle, cela se traduira à chaque fois sur des données sockets disponibles ou non, qui débloqueront select().

    Une connexion entrante sur le socket à l'écoute est aussi considérée comme une « lecture » possible (et pas un événement spécial). En outre, la fermeture d'une connexion est détectée par une lecture de 0 octets côté récepteur. Donc là encore un déblocage en lecture.

    Donc, pour faire une gestion complète de ton serveur dans un premier temps, tu places avec FD_SET tes trois descripteurs (server_sock, client_sock et « listen_sock » ou quelque soit le nom qu'il porte) dans « readfs ».

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

Discussions similaires

  1. Instruction select avec deux critères
    Par the watcher dans le forum DB2
    Réponses: 3
    Dernier message: 01/08/2010, 23h55
  2. [MySQL] Select avec deux champs identiques
    Par avigeilpro dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 26/11/2009, 04h20
  3. Utilisation de select avec un formulaire sans bouton!
    Par solaar dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 15/01/2009, 17h06
  4. Utilisation de select (multiplexage de socket)
    Par caesarvanou dans le forum C++
    Réponses: 5
    Dernier message: 12/07/2006, 15h45
  5. Requête SELECT avec deux champs dans une colonne ??
    Par fredhali2000 dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 08/06/2006, 10h41

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