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 :

Empecher un SIGPIPE sur un send()


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 117
    Par défaut Empecher un SIGPIPE sur un send()
    Bonjour, travaillant actuellement sur un projet en C manipulant les socket je souhaiterais empêcher le traditionnel "broken pipe" d'un send() vers une socket déconnectée.

    Après quelques recherche il s'avère que le flag MSG_NOSIGNAL empêche effectivement ce problème. Mais il s'avère que je ne dispose pas de ce flag dans ma VM (freeBSD 5.5) et je n'ai trouver aucun flag similaire dans socket.h.

    Je ne souhaite pas utilisé select() (et je souhaite éviter poll()). On m'a conseiller d'utiliser setsockopt() mais j'ai un peu de mal.

    Donc j'espère que vous me donnerez quelques pistes pour vérifier la validité d'une socket juste avant de faire le send().

    Merci d'avance.

  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 dewey01 Voir le message
    Donc j'espère que vous me donnerez quelques pistes pour vérifier la validité d'une socket juste avant de faire le send()
    Il faut le faire après coup. Tu appelles send() et tu contrôles le code retour :
    • 0 : deconnecté (ou non connecté)
    • <0 : erreur
    • >0 : OK (nombre d'octets émis).

    tu agis en conséquence.

    Un peu de lecture :
    http://emmanuel-delahaye.developpez....tes-reseaux-c/

  3. #3
    Membre confirmé
    Inscrit en
    Juillet 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 117
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Il faut le faire après coup. Tu appelles send() et tu contrôles le code retour :
    • 0 : deconnecté (ou non connecté)
    • <0 : erreur
    • >0 : OK (nombre d'octets émis).

    tu agis en conséquence.

    Un peu de lecture :

    http://emmanuel-delahaye.developpez....tes-reseaux-c/
    Impossible avec cette solution, send() broken pipe avant d'avoir pu tester sa valeur de retour !

    Mais pour ce faire, j'ai utiliser setsockopt(), de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setsockopt(cs, SOL_SOCK, SO_NOSIGPIPE, (void *)&i, sizeof(i))
    cs étant la socket et i un int initialisée à 1.

  4. #4
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par dewey01 Voir le message
    Impossible avec cette solution, send() broken pipe avant d'avoir pu tester sa valeur de retour !
    Inutile de continuer à faire des suppositions, montre nous ton code si tu veux plus d'aide.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Le problème est simple: send() lève un signal SIGPIPE au lieu de retourner une valeur d'erreur.

    Ne peut-on pas simplement traiter ou ignorer le signal SIGPIPE?
    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.

  6. #6
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Le problème est simple: send() lève un signal SIGPIPE au lieu de retourner une valeur d'erreur.

    Ne peut-on pas simplement traiter ou ignorer le signal SIGPIPE?
    On peut, mais le problème vient généralement du code, exemple, 2 send() qui se suivent et le premier ne vérifie pas son retour.

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 962
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Le problème est simple: send() lève un signal SIGPIPE au lieu de retourner une valeur d'erreur.

    Ne peut-on pas simplement traiter ou ignorer le signal SIGPIPE?
    From UNIX System Programming (K. A. Robbins & S. Robbins, Prentice Hall, PTR) pg 827
    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
     
    int u_ignore_sigpipe() 
    {
        struct sigaction act ;
     
        if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) == -1)
            return -1 ;
     
        if (act.sa_handler == SIG_DFL) {
            act.sa_handler = SIG_IGN ;
            if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) == -1)
                return -1 ;
        }
     
        return 0 ;
    }
    … sauf erreur de frappe en recopiant…

  8. #8
    Membre confirmé
    Inscrit en
    Juillet 2008
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 117
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Inutile de continuer à faire des suppositions, montre nous ton code si tu veux plus d'aide.
    C'est pas une supposition, la solution je l'ai trouvé et je l'ai donné juste au dessus !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setsockopt(cs, SOL_SOCK, SO_NOSIGPIPE, (void *)&i, sizeof(i))
    Cette fonction empêche send() de broken pipe et donc de vérifier sa valeur de retour.

    Cordialement ...

Discussions similaires

  1. [WinCVS] Empecher de committer sur une branche
    Par Wakaboo dans le forum CVS
    Réponses: 0
    Dernier message: 27/09/2007, 17h37
  2. Réponses: 2
    Dernier message: 06/07/2007, 13h27
  3. empecher parcours dossier sur serveur
    Par billoum dans le forum Général Conception Web
    Réponses: 5
    Dernier message: 13/03/2006, 17h39
  4. [VB.Net+Excel] empecher fermeture xl sur beforeClose
    Par sergio_bzh dans le forum Windows Forms
    Réponses: 1
    Dernier message: 03/03/2006, 15h24

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