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 :

[linux] socket comment savoir si est un client est d


Sujet :

Réseau C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 3
    Points : 2
    Points
    2
    Par défaut [resolu][linux] socket comment savoir si est un client est d
    bonjour, apres plusieurs recherche, je n'ai toujours pas trouve comment savoir lorsqu'un client se deconnecte du serveur.
    J'ai egalement un autre probleme, le serveur est cense redirige les msg d'un client vers d'autre client.
    C'est en mode connecte, et chauqe client connecte, un thread lui est associe.
    Ma question est la suivante : ds chaque thread, il y a un appel recv bloquant, qui attend un msg. Je voulais savoir si je pouvais utiliser le descripteur de la socket bloque afin de lui transmettre le msg d'un autre client.
    J'espere avoir etait clair sinon, dites le moi j'esaierai de le dire autrement.
    Merci.

  2. #2
    Membre du Club
    Inscrit en
    Février 2003
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 39
    Points : 46
    Points
    46
    Par défaut
    Pour avoir fait de choses qui ressemble à ce que tu décris, je travaillais avec deux thread pour un socket:

    un thread dédié à l'écoute de ce qui arrive dur la socket.
    un thread dédié à envoyer de l'info sur la socket...

    Ca marchait trés bien.

    Pour détécter qu'un client s'est déconnécté, il existe deux manières:

    Ou il envoit un message propre pour dire coucou, je me deconnecte
    Ou tu met un handler pour capter un message de type SIGPIPE (c'est le message renvoyé par la socket quand elle détecte une deconnexion), mais c'est la que les enmerdes commencent car tu vas voir, la gestion des signaux avec les threads est bien mal aisée....

    N'hésite pas si tu as d'autres questions... eyt explique plus précisement sur quoi tu travailles, j'ai peut etre du code à te refiler....

    Bon we

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    merci bien c cool, donc je v coder sur le client un truc pour la deco, il restera toujours le pb du au cas ou le client plante mais ca devrait deja faire l'affaire en attendant de voir les signaux
    sinon je fait ca juste pour voir les sockets sous linux en c pour l'instant, peut etre deux ou trois idees si j'arrive a bien piger le truc
    bye.

  4. #4
    Membre du Club
    Inscrit en
    Février 2003
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 39
    Points : 46
    Points
    46
    Par défaut
    Si le client plante, le seul et unique moyen de la detecter et de catcher le signal SIGPIPE. Il n'y a pas d'autre moyen. Il va donc te alloir apprendre à gérer les signaux sous unix. Un conseil à ce niveau là. N'utilise que du POSIX!

    Voila, n'hésite pas si tu as d'autres questions.

  5. #5
    Membre du Club
    Inscrit en
    Février 2003
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 39
    Points : 46
    Points
    46
    Par défaut
    Un petit tutorial qui démonte pas mal. Au fait, si tu souhaites ecouter et emettre en même temps, il y a trois possibilités:

    la première (celle que tu as utilisée): les threads
    la deuxième: duplication de process (les fork mais ne fonctionne que sous unix)
    la troisième: le multiplexage d'E/S asynchrone (select, poll etc...)

    http://www.chez.com/vidalc/lf/socket.html

    Bon courage

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    merci bcp, j'ai de quoi bien m'occuper maintenant
    @+

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Points : 75
    Points
    75
    Par défaut
    pardon, je débarque juste 2 ans en retard mais il se trouve que j'ai sensiblement le meme pbm et que je pensais qu'il y avait une autre solution. Pour l'instant ca marche pas trop mais j'aurais besoin d'un avis externe tout de meme!

    Voila je fais un serveur qui cause avec des clients qui ont le droit de se déconnecter quand ils veulent.
    Que je tue mon client ou que je lui fasse fermer la connexion proprement, le probleme est le meme: mon serveur reste bloquer lors de l'appel du send (et oui, le canal de com et détruit).

    Je bosse sur HP unix alors j'ai fouillé les man.

    J'y ai trouvé entre autre une option (a spécifier par setsockopt(..)) qui permet de spécifier le comportement relatifs du close() et du send(). Il y a notemement un cas dans le quel les données non envoyées alors que close a été appelé sont ignorées. (l_onoff = 1 et l_linger = 0).
    J'ai essayé de faire ca mais je suis toujours bloqué sur mon send. Est ce parce que c'est le client qui ferme la connexion et non le serveur? Ou bien c'est parce que je me gourre completement et ca ne peut pas marcher de cette maniere et ma seul chance de m'en sortir et de me taper le SIGPIPE?
    Parce que personnelement, savoir que mon send ne s'est pas passé correctement, ca me suffirait largment et ca m'éviterait bien des déboires....

    Voila pour mes soucis.
    Merci pour les renseignements.


    Seb

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    304
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 304
    Points : 253
    Points
    253
    Par défaut
    Effectivement la solution est plus simple :
    Lorsqu'un client est deconnecté (de quelque maniere que ce soit), tu recois le caractère EOF sur la socket concernée (revc() = 0 (sous linux) ).

  9. #9
    Expert éminent sénior
    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
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par KORTA
    <...> tu recois le caractère EOF<...>
    Par définition, EOF n'est pas un caractère. C'est une constante (int négatif) qui caractèrise l'état d'un flux (erreur de lecture). La cause est déterminée par les fonctions feof() et ferror() avec errno si on veut le détail.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Points : 75
    Points
    75
    Par défaut
    C'est a dire que je suis a niveau du serveur et en emission. Je ne fais pas appel à recv mais à send uniquement.

    Comment on fait pour faire un Send qui ne se bloque pas lorsque la socket est fermée mais qui renvoie une erreur. cf man: send renvoie -1 avec errno = ENOTCONN (ou peut etre autre chose) si la socket n'est pas connectée. En tous cas send renvoie -1 !! Pourquoi chez moi il bloque ce con.
    En plus j'ai essayé de spécifier un socket non bloquante avec fcntl(O_NONBLOCK)!!!!!! Rien n'a faire, il veut pas m'obéir!


    Sinon, y a t il un moyen de testet l'etat d'une socket simplement?


    Seb

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    304
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 304
    Points : 253
    Points
    253
    Par défaut
    Citation Envoyé par traiangueul
    C'est a dire que je suis a niveau du serveur et en emission. Je ne fais pas appel à recv mais à send uniquement.

    Comment on fait pour faire un Send qui ne se bloque pas lorsque la socket est fermée mais qui renvoie une erreur. cf man: send renvoie -1 avec errno = ENOTCONN (ou peut etre autre chose) si la socket n'est pas connectée. En tous cas send renvoie -1 !! Pourquoi chez moi il bloque ce con.
    En plus j'ai essayé de spécifier un socket non bloquante avec fcntl(O_NONBLOCK)!!!!!! Rien n'a faire, il veut pas m'obéir!


    Sinon, y a t il un moyen de testet l'etat d'une socket simplement?


    Seb
    Dans programmation système en C:
    Lorsq'un processus tente d'écrire sur une socket n'ayant pas d'interlocuteur le signal SIGPIPE est declenché, l'appel système renverra une erreur EPIPE.
    Pour la socket non bloquante , tu utilises la bonne procédure fcntl() et O_NONBLOCK , peux tu nous montrer l'architecture du code pour que nous puissons t'aider ..


    Autrement pour ta question tu peux utiliser getsockopt() pour l'état de tes sockets même si rigoureusement c'est l'acces aux option de la socket.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Points : 75
    Points
    75
    Par défaut
    J'ai déja essayé de passer la socket en non bloquant grace fcntl(... O_NONBLOCK) mais ca marche pas. .

    Peut etre je le fais mal mais ca m'étonnerait.
    Pour ce qui est de vous donner des extraits de code, ca va pas etre evident non plus parce que la machine sur laquelle je développe n'a pas d'acces au net....
    Mais je fais des trucs classiques:
    JE crée ma socket d'écoute,
    je regle les options
    Je la place en listen
    J'accepte un client
    Je passe la nouvelle socket obtenue par accept en mode non bloquant
    et je balance les données....

    Mais j'arrive pas a repérer la deconnexion du client

    Comprends po!



    Seb

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    304
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 304
    Points : 253
    Points
    253
    Par défaut
    question futile, mais ta socket est bien en connectée (tcp) et non udp ?

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Points : 75
    Points
    75
    Par défaut
    bien sur.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Points : 75
    Points
    75
    Par défaut
    suite a qq périgrénation, j'ai découvert la fonction select et je me suis dis que je pourrais m'en sortir en testant mon file descriptor avant de faire Send
    1er question: est ce que c'est effectivement une bonne idée?

    donc j'ai fais ceci:
    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
     
    fd_set socks;
    fd_set errors;
    FD_ZERO(&socks);
    FD_ZERO(&errors);
     
    FD_SET(fdDeMaSocket,&socks);
    FD_SET(fdDeMaSocket,&errors);
     
    timeval tv {0,0};
    select(fdDeMaSocket + 1, NULL,&socks,&errors,&tv);
    if(FD_ISSET(fdDeMaSocket,&errors)
        cout << "je suis content de voir qu'il y a un pbm"<< endl;
    if(FD_ISSET(fdDeMaSocket,&socks))
    {
        send (blabla...);
    }
    else
    {
        cout << "je suis content de voir qu'il y a un pbm"<< endl;
    }
    Bon vu ce que j'ai compris de select, je pensais que lorsque je fermerai ma socket au niveau de mon client, cela conduirait le serveur a afficher à un moment ou un autre (et mm 2 fois non?) qu'il est content de voir qu'il y a un pbm.

    Mais figurez vous que je passe toujours par le send mm apres avoir déconnecté mon client et que mon send est toujours bloquant et que je ne m'en sors toujours pas.

    alors ma deuxieme question est: Est ce que je m'y prend mal ou est ce que je comprends mal ou est ce que ca devrait marcher comme je pense et vous non plus vous ne voyez pas pkoi ca va pas.?

    En gros : pourquoi??????


    Merci de m'éclairer un chouïa!


    Seb

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

Discussions similaires

  1. Comment savoir si un fichier/répertoire est en lecture seule
    Par Guigui_ dans le forum Général Python
    Réponses: 3
    Dernier message: 29/12/2004, 17h05
  2. Réponses: 9
    Dernier message: 08/12/2004, 15h36
  3. Comment savoir si une impression s'est bien déroulé?
    Par Cyrilh7 dans le forum C++Builder
    Réponses: 5
    Dernier message: 19/11/2003, 21h49
  4. [VB6] comment savoir si la commande shell est terminée ?
    Par ghyscharlotte dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 30/07/2003, 20h12
  5. Réponses: 4
    Dernier message: 10/09/2002, 18h09

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