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

POSIX C Discussion :

Un client irc avec socket et fork


Sujet :

POSIX C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 26
    Points
    26
    Par défaut Un client irc avec socket et fork
    Bonsoir,

    Je suis en train de coder un clone de client et de serveur irc.
    Je m'appuie de loin sur le protocole irc.

    Le serveur accepte la connection et crée un nouveau processus pour chaque client.
    Pour gérer les clients le serveur et tous les fils partage un segment de memoire contenant un tableau de struct user
    voila la struct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct {
    	int sock;
    	char nick[MAXNAME];
    	struct sockaddr_in addr;
    	socklen_t addr_t;
    	int nbChan;
    	char chan[MAXCHAN][MAXNAME];
    } user;
    Le client se connecte au serveur, crée un nouveau processus pour lire sur le socket et ecrit via le pere.

    Tout marche bien sauf dans le scénario suivant :

    client1 se connecte
    client2 se connecte
    client3 se connecte

    // dans cette phase peut importe l'ordre de connexion au channel
    client2 rejoin le channel #chan
    client3 rejoin le channel #chan
    client1 rejoin le channel #chan

    client1 envoi un message sur le channel. Le seul client a voir le message est client1
    client3 envoi un message sur le channel tous les clients le recoivent
    client2 envoi un message sur le channel les client1 et 2 voient le message

    Lors de l'envoi du message du client1 vers les clients 2 et 3 je recoi une erreur du sendto (ou du send) de type EBADF

    Le descripteur de socket passé en paramètre est bon il correspond bien a celui des différent clients que je veux contacter.

    J'espère avoir été le plus clair possible si ce n'est pas le cas demandez moi

    Merci d'avance pour vos réponses et pour votre compréhension si le problème vous semble ridicule :p

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    1. C'est donc le serveur qui forke, pas le client comme ton titre le suggère
    2. C'est un problème inhérent aux serveurs-fork, les descripteurs sont dupliqués dans le fork mais pas partagés.
      En fait, je serais plutôt du genre à déconseiller en bloc le serveur-fork s'il y a une relation entre les clients (ce qui est le cas pour un chat) : Un serveur-fork, ça marche bien quand les clients sont indépendants, par exemple pour un serveur Web ou SSH (pour du FTP, ce n'est pas indépendant).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 26
    Points
    26
    Par défaut
    J'ai bien vu pendant la phase de dev que le serveur-fork n'est pas pratique.

    Mais ce que je ne comprend pas c'est que tu me dis que les descripteurs ne sont pas partagés.

    Dis moi si je me trompe mais un descripteur n'est qu'un entier ou y a-t'il un system autre qui est caché ?

    Par exemple pour prendre un sujet qui me semble plus simple.

    je crée un programme qui crée un shm et un fils. Le fils ouvre un fichier avec open et place l'entier dans le shm le père pourra-t'il lire ou ecrire sur le fichier ?

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Non, il ne pourra.
    Un descripteur est un index dans une table locale au processus.

    C'est pour ça que chaque processus possède 0, 1 et 2 en entrée standard/sortie standard/sortie d'erreur, même si tu les ouvres dans trois terminaux/consoles différent(e)s...

    Si tu retiriges la sortie standard pour un processus, ça ne change rien aux autres.


    D'ailleurs, si les descripteurs étaient globaux, tu imagines le trou de sécurité ? N'importe quel process pourrait écrire sur n'importe quel fichier ouvert par n'importe quel autre, à moins de contrôler les droits à chaque accès au descripteur...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 26
    Points
    26
    Par défaut
    Donc pas de solution si ce n'est de réouvrir les socket dans chaque fils ?

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Il n'existe pas d'équivalent au DuplicateHandle() interprocess sous unixoïde.

    Tu ne peux donc pas "réouvrir" les sockets dans les fils, car ils ne seraient pas connectés.
    Ce que tu peux essayer de faire, c'est :
    • Faire la transmission en passant par le processus maître ou la mémoire partagée, pour dire "hé, tous les clients! envoyez ça!" (bonne chance pour t'assurer que personne ne modifie avant que tous les clients aient envoyé)
    • Ou abandonner l'idée du serveur-fork : Tout faire dans le même processus, que ce soit par du multithread ou par l'utilisation de la fonction select() (que je recommande).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 26
    Points
    26
    Par défaut
    Merci pour la réponse je pense faire du multithread ce sera la maniere la plus facile a mettre en place vu le code déjà produit.

Discussions similaires

  1. [HF11] Client serveur avec Socket
    Par bakouly dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 30/06/2013, 21h51
  2. client http avec socket
    Par ben83510 dans le forum Réseau
    Réponses: 5
    Dernier message: 25/04/2011, 23h20
  3. Problème pour un client IRC avec Indy9/D7
    Par Ren97 dans le forum Web & réseau
    Réponses: 2
    Dernier message: 05/01/2008, 22h16
  4. Client Irc avec IdIRC1 (indy 9)
    Par Coussati dans le forum Web & réseau
    Réponses: 1
    Dernier message: 21/11/2005, 23h29

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