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 :

Problème de socket bloquant et select sans effet.


Sujet :

Réseau C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 11
    Points
    11
    Par défaut Problème de socket bloquant et select sans effet.
    Bonjour !

    J'ai cherché longuement sur le net pour trouver une solution à mon problème et aucune ne semble fonctionner...
    Je cherche à faire une sorte de forwarder "simple" d'une ip/port vers une autre...

    Le programme se lance et attend la connexion d'un client.
    Une fois le client connecté, le programme ouvre un autre socket vers un server.
    ensuite il forward les données envoyées par le server au client et inversement.

    Mon premier problème a été rencontré avec le "recv" bloquant. J'ai donc cherché comment le rendre non bloquant... J'ai trouvé alors "FIONBIO" et la ça semblait marcher dans un premier temps mais après cela recv retournait "-1" tout le temps même si recv avait effectivement lu les données...

    Cela a eu pour effet de planter toute la gestion des erreur et par dessu le marcher de faire augmenter la charge CPU jusqu'à 50% pour ce process seul !


    J'ai donc abandonné les sockets non bloquants et me suis penché sur "select".

    J'ai donc procédé comme suit (code nettoyé des traitements) :
    les fonctions CreateServerSocket() et CreatClientSocket() sont logue et pas interessantes, elles retourenes les socket "paramétrés"


    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
    SOCKET ServerSock = CreateServerSocket(2654);
        SOCKET ClientSock = CreateClientSocket(6667);
        fd_set ServerReadfds;
        fd_set ClientReadfds;
     
        FD_ZERO(&ServerReadfds);
        FD_SET(ClientSock, &ServerReadfds);
     
        FD_ZERO(&ClientReadfds);
        FD_SET(ServerSock, &ClientReadfds);
        int ret;
     
        do {
                select(ClientSock+1, &ServerReadfds, NULL, NULL, NULL);
                if(ret = FD_ISSET(ClientSock, &ServerReadfds))
                {
                    printf("New incomming datum from Server ! (%d)\n",ret);
     
                  //ici je traite le recv du 1er socket....
     
                }
     
                select(ServerSock+1, &ClientReadfds, NULL, NULL, NULL);
     
                if(ret = FD_ISSET(ServerSock, &ClientReadfds))
                {
                    printf("New incomming datum from Client ! (%d)\n",ret);
     
                  //ici je traite le recv du 2e socket....
     
                }
         } while(1)
    Le problème est que mes tests "FD_ISSET()" retournent toujour 1 ! Donc je reste toujours bloqué sur les recv...

    Merci pour votre aide !

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Attention, tes fd_set doivent être réinitialisés dans la boucle...

    Mais je ne pense pas que ce soit la source de ton problème.

    PS: Pour le 50%, sois content d'avoir un bi-cœur.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    Ben j'ai essayé diverses choses avec les fd... Ne connaissant pas trop ce principe j'ai cherché à me documenter avant de poser la question.

    mais qu'entends tu par "les réinitialiser dans la boucle ?

    il faut que je déplace

    FD_ZERO(&ServerReadfds);
    FD_SET(ClientSock, &ServerReadfds);

    FD_ZERO(&ClientReadfds);
    FD_SET(ServerSock, &ClientReadfds);

    dans mon do... while ?

    Il me semblait que "FD_SET" servait à créer un descripteur de fichier dans ServerReadfds qui était une sorte de "lien" vers le socket ? De ce fait je ne comprends pas ce qui doit être réinitialisé ? L'appel par select change le contenu de &ServerReadfds ? ou bien le IS_SET ?

    Tous les exemple que j'ai trouvé n'utilisent qu'un seul fd (appliquer FD_SET sur les 2 socket avec le meme fd...) Comme cela ne marchait pas je les ai "séparé". En créant un ServerReadfds et un ClientReadfds....

    Meme les exemples simples "tout prèt" ne fonctionnent pas a la compilation !

    Je suis sous windows 7 RC1 peut être est ce la source du problème mais il ne me sembla pas qu'il y a de changement dans "winsock2" entre les versions de windows.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Oui, l'appel par select change le contenu, c'est justement pour ça que FD_ISSET marche!

    En fait, select() fait l'équivalent d'un FD_CLR sur tous les sockets qui ne sont pas actifs.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    Merci pour le retour !
    J'ai tout essayé et rien ne fonctionne, je fini toujours par me retrouver bloqué sur un recv sans comprendre pourquoi... Et même parfois le recv echoue maintenant alors que cela n'arrivait jamais !

    Je ne sais pas si le soucis est avec le select ou avec le FD_ISSET() j'ai fait afficher divers test et le FD_ISSET() retourne toujours 1 !

    Ou alors c'est le socket qui est mal déclaré et il faut le paramètrer ? Comme lorsqu'on le rend non bloquant ?

    Quand on lit un socket server et un socket client c'est bien le 1er paramètre de descripteur qu'il faut checker ?

    Je capte vraiment pas ce qui cloche tous les exemples que j'ai trouvés sont de ce type sauf qu'ils ne traitent qu'un seul socket "server" avec plusieurs clients. Je vais me faire une machine linux avec virtualbox voir si ca marche sous linux... Ca me permetra d'avoit un code portable meme si ca marche aps sous windows

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Points : 4
    Points
    4
    Par défaut répense
    bonjour asmerisme,

    dans les tds on ajoute la fonction select entre une boucle while, et on pensé qu'elle marge, mais lorsque on n'est arivé au tp pour écrire le code, j'ai remarqué que la fonction select ce bloque lors du premier message, apret il recommance a m'affiché le message plusieur foie, et lorsque j'ai dommander au prof, il ma dit que le contenu de la socket réste encor, il n'est pa vidé apret la réception de ce dernier, donc il ma dit si je veux recevoir d'autre message, il fout ajouter la fonction accepte à l'intérieur de la boucle, et sa marche, mais le problème si j'ai plusieurs pc ^^

Discussions similaires

  1. Problème Swing / socket bloquant
    Par soussou92 dans le forum AWT/Swing
    Réponses: 0
    Dernier message: 12/05/2010, 14h29
  2. problème de socket bloquante
    Par phoenixatareva dans le forum C
    Réponses: 3
    Dernier message: 25/03/2010, 14h16
  3. problème bloquant avec "SELECT LAST_INSERT_ID()"
    Par r2d2abc dans le forum JDBC
    Réponses: 15
    Dernier message: 21/04/2009, 02h56
  4. Selection sans critères pour un publipostage
    Par Johnjohn dans le forum Access
    Réponses: 23
    Dernier message: 17/06/2003, 12h51
  5. Sans effet: StringGrid1->Cells[1][1][2] = c ?
    Par Xavier dans le forum C++Builder
    Réponses: 3
    Dernier message: 27/11/2002, 11h32

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