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++Builder Discussion :

Eviter qu'un SocketClient se reconnecte +ieurs fois ou/et déconnecter un SocketClient


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 135
    Par défaut Eviter qu'un SocketClient se reconnecte +ieurs fois ou/et déconnecter un SocketClient
    Bjr,

    La longueur d'une chaine d'un titre n'étant pas assez longue pour ma discussion, je présice que je cherche un raisonnement et bien-sur des exemples de codes pour:

    1/- Réaliser une déconnection d'un SocketClient d'un SocketServer au bout d'un certains temps d'inactivité (en minutes),

    2/- Eviter qu'un SocketServer reçoit plusieurs SocketClient pour un même client.

    Dans le cas "2", on imagine qu'un Client se connecte pour la première fois à mon Serveur. Il y a donc la creation d'un SocketClient sur mon Serveur. Ils s'échangent des data et pour une raison quelconque mon Client se déconnecte (baisse d'alimentation etc...). Mon serveur ne déconnecte pas (proprement ou non) ce SocketClient car le Client lui-même n'en a pas fait la demande puisque c'est un accident.
    Mon Client n'ayant pas terminé ce qu'il avait à faire se connecte à nouveau à mon Serveur. Du coup mon Serveur perçoit le même Client comme un nouveau Client en lui affectant un nouveau Socket, et SocketHandle différent. Comment faire pour que mon Serveur ferme correctement l'ancien SocketClient avant d'accepter la nouvelle connexion de ce même Client?
    Je travaille en mode non bloqué et il m'est impossible de travailler dans le mode bloqué.
    Ai-je besoin d'un thread?

    Merci

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2004
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 51
    Par défaut
    Bonjour,

    Je te propose quelques pistes... ça vaut ce que ça vaut

    1/ Avec des Timers peut-être ? Côté client, un timer se réinitialiserait à chaque fois qu'il envoie des données au serveur. Si rien n'est transmis au serveur dans le délai imparti, alors il envoie un message d'info au serveur disant qu'il se déconnecte pour cause d'inactivité

    J'ai pensé mettre le timer côté client plutôt que côté serveur pour économiser des ressources... s'il devait y avoir 5000 clients je ne sais pas quel serait l'impact sur les performances ?


    2/ Là faut voir comment tu gères les clients... J'imagine que tes clients sont regroupés dans des listes; est-ce que tu ne pourrais pas créer une liste pour les déconnexions sauvages ? Quand une connexion est coupée tu places ton client dans cette liste. Et quand un client cherche à se connecter tu vérifies d'abord s'il n'est pas dans cette liste ? Selon comment tu gères tes clients tu dois pouvoir les retrouver par un point commun ( login + mdp ? Id unique ?).

    Vala c'était ma modeste contribution ^^

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 135
    Par défaut
    Merci pour ta contribution

    1-/ Ta solution est intéressante mais j'en reviens de suite à un prob qui que se passe-t-il si le client se réinitialise et se reconnecte au serveur alors que son delai n'a pas expiré? En principe le serveur crée un nouveau SocketClient jusqu'aux informations de l'adresse IP identique qui risque de créer un conflit/bug au niveau du serveur. C'est pour ça que je me demande s'il ne faut pas aussi un Timer du coté Serveur.

    2-/
    J'imagine que tes clients sont regroupés dans des listes; est-ce que tu ne pourrais pas créer une liste pour les déconnexions sauvages ?
    Mais comment détecter une déconnection sauvage ou non, car dans ce que tu écris si mon Client se connecte correctement (@IP+Login+Pwd) rien ne l'empêche d'être victime d'un accident d'alimentation. Dans ce cas que fait le serveur tjs à la reconnection d'un Client ayant les même paramètres TCP.

  4. #4
    Membre confirmé
    Inscrit en
    Juillet 2004
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 51
    Par défaut
    Alors, alors

    Tatouillons un peu de code !
    Commençons par la classe client (côté serveur donc)... Je ne mets que le minimum pour plus de clarté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class client
    {
     AnsiString pseudo;  // pseudo du client
     AnsiString Id;        // son Id unique (ip + login + mdp + nomdupc + serial du DD) par exemple ^^
     TCustomWinSocket *mysocket; // pointeur vers le socket attribué au client
     bool AQuitteProprement;  // false par défaut
    };

    Dans l'évènement de connexion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //------------------------------------------------------------------------
    // ***** OnClientConnect *****
    //------------------------------------------------------------------------
    void __fastcall TForm1::sockClientConnect(TObject *Sender, TCustomWinSocket *Socket)
    {
     client *c = new client;
     c->mysock = Socket;   // notre pointeur pointe sur le socket attribué
    // Après tu mets ton client dans une liste (TList, liste chainee etc)
    MaListeDeClients->Ajouter (c);
    }
    J'en arrive à ce qui te préoccupe ^^
    Dans l'aide de Borland sur l'évènement de déconnexion du client on trouve ça :
    The TServerClientWinSocket that describes the server endpoint of the client connection is freed after OnClientDisconnect
    Donc, on peut se servir du pointeur TCustomWinSocket renvoyé par l'évènement pour rechercher le client dont il s'agit.

    Par ailleurs, si un client quitte proprement en prévenant le serveur alors tu passe son bool AquitteProprement à True.

    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
     
    //------------------------------------------------------------------------
    // ***** OnClientDisconnect *****
    //------------------------------------------------------------------------
    void __fastcall TForm1::sockClientDisconnect(TObject *Sender, TCustomWinSocket *Socket)
    {
     // Socket est le socket du client qui a quitté (sauvagement ou pas)
     // Sachant que le socket ne sera libéré qu'après la fin de l'évènement
     // le pointeur est toujours valide
     // On va alors chercher dans notre liste de clients, lequel a un pointeur identique.
    client *c = MaListDeClients->RenvoyerClientSelonSocket (Socket);
    c->mysocket = NULL;
     
    // Après tu fais ce que tu veux de ton client :D
    if (c->AQuitteProprement) {FaireCeci (c);}
    else {FaireCela (c);}
    }

    Voilà, j'espere que ça pourra t'aider

  5. #5
    Membre Expert
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Billets dans le blog
    1
    Par défaut
    bonjour,
    une solution très simple largement utilisée dans les applications professionnelles est l'utilisation d'un "signe de vie".
    le principe utilisé est très simple,le seveur envoie a chaque client connecté
    un datagrame de test à intervalle régulier , (par exemple toutes les minutes), chaque client répond a ce datagramme.
    il ne reste plus alors au serveur a contrôler que chaque client connecté aie répondu au datagramme, dans le cas contraire le serveur déconnecte la connection inactive

    Cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 135
    Par défaut
    Merci pour vos aides.
    Néanmoins je reste perplexe sur par exemple la solution de DjmSoftware qui me semble pas complète car si je crée un speudo protocole de "signe de vie" entre mes clients et mon serveur toutes les minutes, que se passe-t-il si au bout de 30sec j'ai l'un de mes clients qui s'est déconnecté et se reconnecte automatiquement avant le signe de vie?
    De mes tests je vois bien que le serveur crée un nouveau SocketHandle, pourtant l'adresse IP est la même.
    Que se passe-t-il une fois que le serveur a détecté qu'il y a deux SocketHandle avec des SocketRemoteAddress identique?
    Je reformule ma question plus précisément:
    Existe-t-il un évènement relatif aux sockets du serveur qui peut se déclencher juste avant que le SocketServeur est l'attribution du SocketRemoteAddress afin de déconnecter un Socket ayant déjà reçu ce même SocketRemoteAddress, en vu d'éviter une erreur ou bug?

Discussions similaires

  1. Eviter qu'un visiteur s'inscrive plusieurs fois
    Par bernard26000 dans le forum Langage
    Réponses: 2
    Dernier message: 06/01/2015, 15h12
  2. [MySQL] comment eviter de faire 2 fois la meme requete
    Par lelapinrusse dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 04/05/2008, 00h14
  3. Réponses: 10
    Dernier message: 18/07/2007, 17h36
  4. Eviter de charger la meme liste 365 fois
    Par ReaseT dans le forum ASP
    Réponses: 2
    Dernier message: 02/10/2006, 14h04
  5. [API WIN] Eviter qu'un prog se lance 2 fois...
    Par asher256 dans le forum Windows
    Réponses: 2
    Dernier message: 07/10/2005, 15h58

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