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

Delphi Discussion :

Gestion d'un IdIcmpClient dans un thread


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    186
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2003
    Messages : 186
    Par défaut Gestion d'un IdIcmpClient dans un thread
    Bonjour à tous

    Je vous explique brièvement mon problème :
    Je parcours un range d'adresse IP. Je dois faire un Ping sur chaque adresse.
    Je veux gérer celà dans un Thread qui me permettra d'avoir la main sur mon programme et aussi pour que je puisse arrêter à tout moment mon application.
    La fonction PingHost(Host); fonctionne très bien dans une Unit mais dans le Thread elle me pose des problème...
    Mon applic ne plante pas mais en mode pas-à-pas je remarque qu'il ne passe pas la valeur du Host. Il me met : "Host = Symbol was eliminated by linker".

    Voici mon 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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    type
      ThreadScanIP = class(TThread)
      private
        FProgressForm: TfrmProgressBar;
      protected
        procedure Execute; override;
        procedure OnTerminateProcedure(Sender: TObject);
      public
        procedure PingHost(Host: string);
        constructor Create(Suspended: Boolean);
      end;
     
    implementation
     
     
    constructor ThreadScanIP.Create(Suspended: Boolean);
    begin
      FreeOnTerminate := True;
      inherited Create(Suspended);
      FProgressForm := TfrmProgressBar.Create(nil);
      FProgressForm.Show;
      OnTerminate := OnTerminateProcedure;
    end;
     
    procedure ThreadScanIP.Execute;
    var
      StartIP, EndIP, i, Count: Integer;
      InAddr: TInAddr;
    begin
      frmMain.btnValider.Enabled := False;
      Count := 0;
      FProgressForm.ProgressBar.Max := frmMain.CountIP;
      StartIP := ntohl(inet_addr(PChar(frmMain.IPs)));
      EndIP := ntohl(inet_addr(PChar(frmMain.IPe)));
      frmMain.richedit1.Enabled := False;
      frmMain.richedit1.Clear;
      for i := StartIP to EndIP do //Parcours le range d'adresse IP définit
      begin
        if (i and 255) <> 0 then
        begin
          InAddr.S_addr := htonl(i);
          frmMain.RichEdit1.Lines.Add(inet_ntoa(InAddr)); //adresse IP parcourue
          PingHost(inet_ntoa(InAddr));
          FProgressForm.ProgressBar.Position := Count;
          Inc(Count);
        end;
      end;
      frmMain.richedit1.Enabled := True;
      MessageBox(0, 'Traitement des adresses terminé', 'Scanning IP', MB_OK);
      frmMain.btnValider.Enabled := True;
    end;
     
    procedure ThreadScanIP.OnTerminateProcedure(Sender: TObject);
    begin
      if Assigned(FProgressForm) then
        FProgressForm.Release;
    end;
     
    procedure ThreadScanIP.PingHost(Host: string);
    var
      IdIcmpClient: TIdIcmpClient;
    begin
      IdIcmpClient := TIdIcmpClient.Create(nil);
      with IdIcmpClient do
      begin
        try
          Host := Host;
          ReceiveTimeout := StrToInt(frmOptions.edtTimeOut.Text);
          TTL := StrToInt(frmOptions.edtTTL.Text);
          BufferSize := StrToInt(frmOptions.edtBufferSize.Text);
          Ping;
          case ReplyStatus.ReplyStatusType of
            rsEcho:
              begin
                frmMain.lbLog.Items.Append(format('response from host %s in %d millisec.',
                  [
                  ReplyStatus.FromIpAddress,
                    ReplyStatus.MsRoundTripTime
                    ]));
              end;
            rsError:
              frmMain.lbLog.Items.Append('Unknown error.');
            rsTimeOut:
              frmMain.lbLog.Items.Append('Timed out.');
            rsErrorUnreachable:
              frmMain.lbLog.Items.Append(format('Host %s reports destination network unreachable.',
                [ReplyStatus.FromIpAddress]));
            rsErrorTTLExceeded:
              frmMain.lbLog.Items.Append(format('Hope %d %s: TTL expired.',
                [TTL,
                ReplyStatus.FromIpAddress]));
          end;
        finally
          Free;
        end;
      end;
    end;

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    186
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2003
    Messages : 186
    Par défaut
    Personne n'a une petite idée pour que je passe de bonnes fêtes ?

  3. #3
    Membre Expert

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Par défaut
    D'abord si ton code marche bravo, car théoriquement la VCL n'est pas concue pour être appellée depuis un thread. C'est donc un grand hasard que ta fiche soit correctement dessinée avec tout ses composants... Si ca bugge, je te conseille de revenir à la forme traditionnelle : le thread n'exécute que des requêtes réseaux et commande à sa fiche mère les mises à jour via des appelles à Synchronize(). Mais pour ton problème précis, c'est sans doute car le paramètre "Host" entre en conflit avec la propriété du même nom du IdIcmpClient , implicite à cause du with. Un simple renommage du paramètre fera l'affaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure ThreadScanIP.PingHost(AHost: string);
    var
      IdIcmpClient: TIdIcmpClient;
    begin
      IdIcmpClient := TIdIcmpClient.Create(nil);
      with IdIcmpClient do
      begin
        try
          Host := AHost;

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    186
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2003
    Messages : 186
    Par défaut
    Super Reisubar ça fonctionne nickel...
    J'étais persuadé d'avoir testé en utilisant une variable différente mais... non

    Un grand merci pour ta réponse. Je vais essayer d'implémenter ta technique. Je débute dans la gestion des Thread.

    Bonne fête de fin d'année à tous...

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

Discussions similaires

  1. [WD10] Gestion d'un fenêtre dans un thread différent
    Par Louis Griffont dans le forum WinDev
    Réponses: 23
    Dernier message: 21/06/2010, 09h47
  2. Gestion des évènements dans un thread
    Par kashikai dans le forum SDL
    Réponses: 0
    Dernier message: 25/05/2009, 14h32
  3. Gestion de la mémoire douteux dans un thread
    Par kollyv dans le forum C#
    Réponses: 14
    Dernier message: 01/05/2007, 16h51
  4. Affichage dans un thread // gestion du clavier!
    Par phraides dans le forum SDL
    Réponses: 5
    Dernier message: 08/07/2006, 12h14
  5. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 17h25

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