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 :

[Réseau] select() et accept() sur plusieurs sockets


Sujet :

C++

  1. #1
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut [Réseau] select() et accept() sur plusieurs sockets
    Bonjour,

    Je souhaiterais savoir si il existe une méthode un peu comme select mais pour accepter des connections sur différentes socket...

    Aparemment select ne peux etre utilisé que sur une socket déja connectée et ca m'éviterais de créer une thread pour chaque attente de connection vu que accept est bloquant.

    Si quelqu'un connais la réponse ou bien si quelqu'un peux m'indiquer au moin une méthode d'utilisation pour faire un accept non bloquant histoire de créer cette fonction moi meme a la limite, ca serait bien

    merci
    J'aime pas les épinards... Mais alors pas du tout

  2. #2
    Membre habitué Avatar de ken_le_videur
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 129
    Points : 145
    Points
    145
    Par défaut
    Pour rendre un socket non bloquant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	u_long argp=1;
    	ioctlsocket(sock, FIONBIO, &argp);

  3. #3
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    j'ai besoin d'un ptit conseil la

    On m'as toujours dit de ne pas utiliser les socket non blocante car elles étaient gourmandes en cpu... Cependant, je pense que la fonction select par exemple utilise ce genre de Procédé pour lire sur la liste de socket...

    Comment cela se passe-til a l'interieur de ce genre de fonction ??? Il y a un timout dans la boucle d'attente ce qui ralentis les test et donc diminue la consommation CPU tout en diminuant la fréquence des tests sur chaque socket (je trouve ca bof)...

    Ou bien la en ecrivant je vien d'avoir l'idée de créer une class qui gere la liste de socket en les placant dans des tread séparées dont elle aurais la gestion... Cela me parais tres compliquer et risque de poser pas mal de probleme de synchronisation cependant ca me parais moin gourmand et plus propre...

    Est ce que je me trompe ?
    J'aime pas les épinards... Mais alors pas du tout

  4. #4
    Membre habitué Avatar de ken_le_videur
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 129
    Points : 145
    Points
    145
    Par défaut
    C'est pas un read sur un socket non bloquant qui bouffe le cpu, c'est l'utilisation faite:
    Si tu fait une boucle jusqu'à ce qu'il n'y ai plus rien à lire sans faire un petit temps d'attente ==> paf les perfs dégringolent.
    Il faut juste insérer un petit temps d'attente entre les lectures pour permettre au buffer de se remplir

  5. #5
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Bah finalement ca vas pas :/ Le principe d'attente fonctionnais bien mais le probleme c'est que je doit effectué des read / Write sur ce socket et eux doivent etres synchrone...

    Donc si j attend d'autres client sur ce meme socket tout en communiquant avec les clients déja connectés ca vas pas le faire...

    Est ce que je doit faire toute mes lectures / ecritures en asynchrone ??? ca m'embete pas mal mais si j ai pas le choix ...

    Vous en pensez quoi ?
    J'aime pas les épinards... Mais alors pas du tout

  6. #6
    Membre habitué Avatar de ken_le_videur
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 129
    Points : 145
    Points
    145
    Par défaut
    Tu peux rerendre la connection bloquante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       u_long argp=0;
       ioctlsocket(sock, FIONBIO, &argp);

  7. #7
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Oui je sais mais le probeme c'est que si je rend la connection blocante elle le devient aussi pour les attentes de connections... vu que j'utilise le meme socket pour accepter les connection et pour communiquer avec mes clients...
    Je vais expliquer un peux mieux ce que fais mon serveur car j'ai été tres flou la dessus :

    TantQue (ServeurActif)
    {
    Attente d'une connexion sur 3 socket différente()
    Si (UnClientSeConnecte)
    {
    Switch (PortSurLequelSeConnecteLeClient
    case xxx : LancementThreadPourGérérLeClientSurLePortXXX();
    case yyy : LancementThreadPourGérérLeClientSurLePortYYY();
    }
    }
    Sachant que la Thread qui gere le client utilise le meme socket que la socket de connexion on vois bien ici que ca poserais un probleme...

    Il doit bien y avoir un moyen d'effectué une lecture sur une socket non blocante tout de meme... aparemment recv ne le permet pas mais bon. Je vais m accrocher
    J'aime pas les épinards... Mais alors pas du tout

  8. #8
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 54
    Points
    54
    Par défaut
    vu que j'utilise le meme socket pour accepter les connection et pour communiquer avec mes clients...
    :
    ca fait un bout de temps que j'ai laissé tomber les sockets de base, trop bas niveau pour moi, mais generalement quant le serveur fait accept(), on cree le client (thread) avec le socket que renvoie accept(), qui est different du "SuperSocket" (si je veux) du serveur

  9. #9
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Oula attend la... je commence a me paumé dans mes sockets... G pas le code sous les yeux la mais je crois que je me sert du "supersocket" pour envoyer un message au socket de retour...

    mhmhmhmm....

    En tout cas je comprend pourquoi tu as arreter d'utiliser les sockets de bases LOL

    Je vais vérifier si g pas fais une connerie a ce niveau la (ca m arrangerais bien dailleur )
    J'aime pas les épinards... Mais alors pas du tout

  10. #10
    Membre émérite
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Points : 2 568
    Points
    2 568
    Par défaut
    C'est toujours bien sympa les sockets de bases
    D'ailleurs j'y suis en plein dedans en ce moment juste pour le fun en +, bon ok quand cela ne fonctionne pas c’est super lourd lol


    Voilà un bout de code pour t’aider un peu dans ta recherche

    Ton application n’est pas bloquante
    Il attend un peu check s’il y a un message, s’il n’y en a pas il continu et revient via le while.

    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
     
    	timeval time_socket;
    	fd_set t_fd_recv_read;
    	SOCKET current_socket;
    .....
     
    while(server_open)
    {
    	FD_ZERO(&t_fd_recv_read);
    	FD_SET(current_socket, &t_fd_recv_read);
     
    	// Time for the select
    	time_socket.tv_sec=0;				//send_wait_time_s;
    	time_socket.tv_usec=5000;			//send_wait_time_microsecond;
     
    	select(current_socket, &t_fd_recv_read, 0, 0, &time_socket);
    	if(FD_ISSET	(current_socket, &t_fd_recv_read))
    	{
    	// Un message est arrivé le traiter
    .....
    	}
    }

  11. #11
    Membre averti Avatar de Goundy
    Profil pro
    Étudiant
    Inscrit en
    Avril 2005
    Messages
    605
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2005
    Messages : 605
    Points : 386
    Points
    386
    Par défaut
    Citation Envoyé par Higestromm Voir le message
    Je souhaiterais savoir si il existe une méthode un peu comme select mais pour accepter des connections sur différentes socket...
    euh.. ?
    select() fait ça hein
    Tu set tes FDS en read et chaque fois qu'un fd *isset* tu accept()
    Compil your life guy!
    The Aures Project

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Voir aussi éventuellement du côté de poll() ...

    Pour abonder dans le sens de Goundy, un extrait de la page de accept() manuel :

    In order to be notified of incoming connections on a socket, you can use select(2) or poll(2). A readable event will be delivered when a new connection is attempted and you may then call accept() to get a socket for that connection. Alternatively, you can set the socket to deliver SIGIO when activity occurs on a socket; see socket(7) for details.

  13. #13
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Utilise boost.asio, c'est tellement plus simple.
    Boost ftw

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    Tu peux aussi aller regarder du côte de ce fil.
    En gros:
    Le select optimise les attentes d'évènements sur toutes tes sockets: socket serveur avant l'accept, socket client pour le connect, sockets connectées pour les read/write. Une solution peut être de couper en deux threads: un dédié à la connexion des clients et un dédié aux échanges. Dans le premier thread, tu as juste une socket, qui fait un listen non bloquant et se met en attente sur un select. Lorsqu'elle en sort car demande de connexion, elle fait l'accept et envoi le nouvel handle de socket à l'autre thread. L'autre thread fait les read et les write en mode asynchrone en attendant avec un select. La sortie d'un select sur un évènement read signifie que tu pourras faire un read sans que cela bloque. La sortie sur un évènement write signifie que le buffer d'émission est disponible. Attention, cela peut vouloir dire qu'un send va réussir mais pas forcément sur la totalité du buffer demandé. Il faut toujours vérifier que la taille effective prise en compte par le send. L'important est d'écrire alors le bon automate sur ce second thread.

Discussions similaires

  1. Select .. inner join sur plusieurs tables
    Par 3titi92 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 08/01/2015, 12h19
  2. select avec calcul sur plusieurs colones ?
    Par mohe27 dans le forum SQL
    Réponses: 7
    Dernier message: 08/03/2011, 11h42
  3. Sélection sur plusieurs sockets
    Par philou_rt dans le forum Réseau
    Réponses: 2
    Dernier message: 02/07/2008, 15h41
  4. Lecture non bloquante sur plusieurs Sockets avec nio
    Par ratakses dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 19/04/2007, 16h14
  5. [MySQL] Afficher une selection d'enregistrement sur plusieurs pages
    Par largolgd dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 09/03/2006, 22h20

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