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 :

[INDY]Threads->LockList();


Sujet :

C++Builder

  1. #1
    Membre éclairé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Par défaut [INDY]Threads->LockList();
    Bonjour,
    J'utilise un serveur TCP Indy (version 9) et au moment de la fermeture du serveur, je veux envoyer un messages à tous les clients connectés.
    Voici le code :
    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
    23
    24
    25
    26
       if (Serveur1TCP == true)
          {
          TList *List = new TList();
          try {
              List = TCPS1->Threads->LockList();
              int I = 0;
              while (I < List->Count)
                    {
                    TIdPeerThread(List->Items[I]).Connection->WriteLn("Serveur stop. Vous allez être déconnecté."); // ligne posant problème
                    I++;
                    }
              TCPS1->Threads->UnlockList();
              delete List;
              }
          catch ( ... )
                {
     
                }
          try {
              TCPS1->Active = false;
              }
          catch ( ... )
                {
     
                }
          Serveur1TCP = false;
    Quand le code passe sur la ligne posant problème, une exeption arrive (il n'y a qu'un client connecté :

    ---------------------------
    Notification d'une exception du débogueur
    ---------------------------
    Le projet serveur.exe a provoqué une classe d'exception EAccessViolation avec le message 'Violation d'accès à l'adresse 00402BE4. Lecture de l'adresse 00000000'. Processus stoppé. Utilisez Pas-à-pas ou Exécuter pour continuer.
    ---------------------------
    OK Aide
    ---------------------------
    Il n'y a pas de bug si aucun client est connecté et si ce bug a lieu, il y a ensuite ce message quand j'arrive à la ligne qui ferme le serveur :

    ---------------------------
    Notification d'une exception du débogueur
    ---------------------------
    Le projet serveur.exe a provoqué une classe d'exception EIdTerminateThreadTimeout avec le message 'Terminate Thread Timeout'. Processus stoppé. Utilisez Pas-à-pas ou Exécuter pour continuer.
    ---------------------------
    OK Aide
    ---------------------------
    Je me suis inspiré de cette page :
    http://delphi.developpez.com/faq/?pa...veurversclient

    Je n'ai pas mis Pred() parce que je ne sais pas ce que c'est comme fonction, il n'y a rien dans l'aide et C++builder me dit qu'il jne connait pas cette fonction.

    Quelqu'un sait comment résoudre ce problème?

    Merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Par défaut
    Donc, le programme plante s'il y a un client de connecté à la ligne indiqué.
    Seulement, même si aucun client se connecte, le programme plante à la fermeture dès que cette ligne est ajouté (locklist). Elle ne fait pas planté tout de suite mais quand le logiciel se ferme.

    Comment résoudre se problème?

    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
    23
    24
    25
    26
    27
    28
    29
    30
       if (Serveur1TCP == true)
          {
          TList *List = new TList();
          try {
              List = TCPS1->Threads->LockList(); //ligne faisant planté à la fermeture
          try {
              int I = 0;
              while (I < List->Count)
                    {
                    TIdPeerThread(List->Items[I]).Connection->WriteLn("Serveur stop. Vous allez être déconnecté."); //plantage avec au moins un client de connecté
                    TIdPeerThread(List->Items[I]).Connection->Disconnect();
                    I++;
                    }
              }
          catch ( ... )
                {
                }
          }
          __finally {
                    TCPS1->Threads->UnlockList();
                    }
          delete List;
          try {
              TCPS1->Active = false;
              }
          catch ( ... )
                {
     
                }
          Serveur1TCP = false;

  3. #3
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 8
    Par défaut QQ Erreurs de code il me semble...
    Bonjour,
    Au risque de dire une betise :

    Le pointeur sur la TList retournée par la fonction TThreadList::LockList() est un pointeur sur une liste de void*.
    De part sa provenance (la fonction LockList...), cette TList ne contient que des TIdPeerThread*, il faut donc obligatoirement faire un cast vers des pointeurs de TIdPeerThread :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    [...]
    while (I < List->Count)
    {
        ((TIdPeerThread*)(List->Items[I]))->Connection->WriteLn("Serveur stop. Vous allez être déconnecté.");
        ((TIdPeerThread*)(List->Items[I]))->Connection->Disconnect();
        I++;
    }
    [...]
    Voila qui pourrait resoudre le bug lorsqu'il y a des clients connectés...

    Pour le bug qui se produit en l'absence de client, il me semble, d'apres l'erreur de timeout, que la liste de thread reste verrouillée...

    PS : Je pense que l'instanciation de ta TList n'est pas nécessaire..
    ... et que le
    est plutot dangeureux car tu libere le pointeur fournit par LockList()...

    Conseil (1) : Le 'for' est plus "sûr" que le 'while' (il evite généralement les malencontreuses boucles infinies)
    Conseil (2) : L'identation du code permet une lecture et une comprehension rapide du code... Et en plus ça permet de savoir à quel 'try' les 'catch' font référence... ;-)

  4. #4
    Membre éclairé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Par défaut
    Bonsoir,

    Merci de votre réponse. Maintenant, j'ai obtenu ce code et il fonctionne bien. J'ai utilisé while parce que cela ne paraissait bien convenir à cette boucle.

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
       if (Serveur1TCP == true)
          {
          TList *List = new TList();
          try {
              List = TCPS1->Threads->LockList();
          try {
              int I = 0;
              while (I < List->Count)
                    {
                    ((TIdPeerThread*)(List->Items[I]))->Connection->WriteLn("Serveur stop. Vous allez être déconnecté.");
                    ((TIdPeerThread*)(List->Items[I]))->Connection->Disconnect();
                    I++;
                    }
              }
          catch ( ... )
                {
                }
          }
          __finally {
                    TCPS1->Threads->UnlockList();
                    }
          List = NULL;
          delete List;
          try {
              TCPS1->Active = false;
              }
          catch ( ... )
                {
     
                }
          Serveur1TCP = false;

  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,
    comme l'a fait justement remarqué rConty
    il ne faut pas créer un objet TList
    le code suivant est donc correct

    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
     
      if (Serveur1TCP == true) 
        { 
          TList *List; // deéclaration d'unPtr sur TList 
          try { 
              List = TCPS1->Threads->LockList(); 
              for(int I=0;n<List->Count;I++)  
               {          
               ((TIdPeerThread*)(List->Items[I]))->Connection->WriteLn("Serveur stop. Vous allez être déconnecté."); 
                    ((TIdPeerThread*)(List->Items[I]))->Connection->Disconnect(); 
               } 
           catch ( ... ) 
                { 
                } 
           TCPS1->Threads->UnlockList(); 
        }
    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 éclairé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Par défaut
    Merci

    Je ne comprend pas grand chose à ces histoires d'objet dynamique et cela ma l'air difficile de savoir quand il faut faire comme ça et quand il faut faire autrement.

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

Discussions similaires

  1. Indy : Liste des Threads Actifs avec leurs propriétés/Membres
    Par micheln dans le forum Web & réseau
    Réponses: 2
    Dernier message: 24/11/2008, 21h12
  2. Indy Terminate Thread Timeout
    Par FredKaes dans le forum Web & réseau
    Réponses: 3
    Dernier message: 16/10/2007, 10h52
  3. Indy et Threads : Readln bloquant.
    Par AraXav dans le forum Langage
    Réponses: 4
    Dernier message: 05/05/2006, 11h26
  4. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53
  5. [Kylix] Runtime error 230 avec INDY
    Par Anonymous dans le forum EDI
    Réponses: 2
    Dernier message: 23/03/2002, 11h51

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