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

Web & réseau Delphi Discussion :

Com TCP/IP Problème TClientSocket et Indy


Sujet :

Web & réseau Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 19
    Par défaut Com TCP/IP Problème TClientSocket et Indy
    Bonjour à tous.

    Je débute en com sur TCP/IP et je suis en cours de développement d'un client pour une liaison avec un automate Schneider (Serveur Carte ETY5103) en modbus IP.
    Je sèche malgré diverses recherches et tests, je viens donc vous solliciter.

    Mon ou mes problèmes se situent sur l'utilisation des composants socket.
    J'ai donc testé deux méthodes avec pour chacune les soucis suivant:

    Avec TClientSocket:
    Les échanges fonctionnent mais lorsque le serveur est sur le réseau Ethernet local, la connexion et les échanges sont beaucoup plus lent qu'avec le serveur distant sur internet!!


    Avec Indy TidTCPClient:
    Les connexions sont rapide dans les deux cas (Local ou distant), mais je ne parviens pas à récupérer correctement la réponse du serveur dans la procédure ci-dessous, qui n'est pas toujours appelée!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure TForm1.Client1Work(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCount: Integer);
    var str: string;
    begin
       str := Client1.IOHandler.ReadLn;
       Trame_rx := str;
       conv_trame_rx;
       ListBox1.Items.Insert(0, 'RX '+Trame_rx_aff);
    end;
    Merci d'avance de votre aide.

    Thierry

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 083
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 083
    Par défaut
    Pour le TClientSocket, c'est étrange, je l'ai utilisée massivement, en réseau local ou via Tunnel SSH lorsque utilisé sur Internet, et évidemment, c'était nettement plus rapide en LAN qu'en WAN

    TidTCPClient, c'est normal, ReadLn attend une fin de Trame (fin défini par ATerminator) donc tant que tu n'as pas de retour charriot par exemple, il continue à lire en boucle ... mais je pense que tu as cette fin de message, sinon tu aurais dit que cela bloquait ...
    je préfère utilisé ce composant aussi en Thread, ... c'est plus efficace, je trouve que les Events (en fait les seuls bon composant Asynchrone c'est TClientSocket, les autres, c'est thread obligatoire, du moins avec les tests que j'ai fait ...)
    Essaye un autre code, il est possible qu'après ton message, il y en ai un autre en fait, et que lorsque tu recçois un seul Event Work, tu as en fait plusieurs messages à lire ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.Client1Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
    var str: string;
    begin
       if AWorkMode = wmRead then
       begin
         SetLength(str, AWorkCount);
         Client1.ReadBuffer(str[1], AWorkCount);
         Trame_rx := str;
         conv_trame_rx;
         ListBox1.Items.Insert(0, 'RX '+Trame_rx_aff);
       end;
    end;
    Tu as quel Delphi ? le 6 ?
    Avec le 7, tu as aussi les TTCPClient (unité sockets), ils fonctionnent pas si mal (avec un thread, je n'ai pas trouvé le mode non bloquant du TClientSocket qui est pratique lorsque l'on a pas envie de faire de thread), je ne les ai utilisé qu'une seule fois
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 19
    Par défaut toujours pas de réception !!
    Bonjour Shai

    Merci de tes réponses

    Je suis en D7 et D2006, j'ai testé dans les deux versions.

    Pour les caractères de fin de Trame je doit oublier car je ne maitrise pas la terminaison de la trame de réponse.
    En fait je captais quelque chose par ce que je ne contrôlais pas : if AWorkMode = wmRead then...

    J'ai donc testé TTCPClient qui se connecte correctement dans les deux cas (local/Distant).
    L'envoie de données est correcte avec la méthode :Tcpclient1.SendBuf(LBuffer,12,0);
    Par contre je ne capte toujours pas les données reçues, toujours pas d'évènement OnReceive :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.TcpClient1Receive(Sender: TObject; Buf: PAnsiChar;
      var DataLen: Integer);
    var Recept:string;
    begin
     
      Showmessage('on Receive') ;
      Recept := Buf[DataLen];
      Trame_rx := Recept;
      conv_trame_rx;
      RichEdit1.Lines.Add('RX '+Trame_rx_aff);
    end;
    J'ai testé en mode bloquant et non bloquant idem pour OnReceive par contre en mode non bloquant l'évènement OnConnect disparait. Est-ce normal?

    Comment gère t'on le buffer de réception???

    Quand à Indy j'obtiens encore moins de résultat..

    Merci d'avance de ton aide

    Thierry

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 083
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 083
    Par défaut
    Comme je l'ai dit, les modes non Bloquant (via Event) des nouveaux composants, sont semble-t-il moins efficace que ceux du TClientSocket, c'est que l'on ne doit pas bien les utiliser ...

    sinon, moi j'ai écrit ça

    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
    class function TRISToPACS.Connexion(const Host, Port: string; const EndOfLine: string = Control_D; BlockingTime: Cardinal = 100; WaitOnTerminateTime: Cardinal = 10000): Boolean;
    var
      TcpClientToPACS: TTcpClient;
    begin
       if Assigned(_InternalThread) then
       begin
          Result := False;
          Exit;
       end;
     
       TcpClientToPACS := TTcpClient.Create(nil);
       TcpClientToPACS.RemoteHost := Host;
       TcpClientToPACS.RemotePort := Port;
     
       Result := TcpClientToPACS.Connect();
       if Result then
         _InternalThread := TTcpClientToPACSThread.Create(TcpClientToPACS, EndOfLine, BlockingTime, WaitOnTerminateTime)
       else
         TcpClientToPACS.Free();
    end;
    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
    procedure TTcpClientToPACSThread.Execute();
    var
       InText: string;
       OutArray: TStringDynArray;
       ioa: Integer;
       Work: TRISToPACSWork;
    begin
       SocketState := ssNone;
     
       while not Terminated and FSocket.Connected do
       begin
          if PopWork(Work) then
          begin
             case Work.WorkType of
               wtFile : Read...WorkListFile(Work.Data, OutArray);
               wtMsg : begin
                 setLength(OutArray, 1);
                 OutArray[0] := Work.Data;
               end;
             end;
     
             for ioa := Low(OutArray) to High(OutArray) do
             begin
               if OutArray[ioa] <> '' then
               begin
                 SocketState := ssWriting;
                 try
                   FSocket.Sendln(OutArray[ioa], FEndOfLine);
                   TRISToPACS.WriteLog(FSocket.RemoteHost, FSocket.RemotePort, 'OUT', OutArray[ioa]);
                 finally
                   SocketState := ssNone;
                 end;
                 Sleep(1);
                 SocketState := ssReading;
                 try
                   InText := FSocket.Receiveln(FEndOfLine);
                   TRISToPACS.WriteLog(FSocket.RemoteHost, FSocket.RemotePort, 'IN', InText);
                 finally
                   SocketState := ssNone;
                 end;
                 Sleep(1);
                 SocketState := ssReconnecting;
                 try
                   FSocket.Disconnect(); // j'ai eu un soucis, cela vient du serveur qui me chasse après une lecture ...
                   FSocket.Connect();
                 finally
                   SocketState := ssNone;
                 end;
               end;
            end;
          end;
     
          Sleep(FBlockingTime);
       end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/05/2011, 01h59
  2. Problème d'installation Indy 10
    Par Booster2ooo dans le forum Composants VCL
    Réponses: 3
    Dernier message: 30/08/2010, 18h14
  3. Problème avec composant Indy
    Par yoshï dans le forum C++Builder
    Réponses: 2
    Dernier message: 17/09/2007, 11h50
  4. [C++]Importation d'une DLL de com TCP en c#
    Par Raton dans le forum MFC
    Réponses: 10
    Dernier message: 11/05/2006, 09h59
  5. Réponses: 3
    Dernier message: 05/05/2004, 10h23

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