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 :

[IdTcpServer]Envoi d'objet ou record avec Stream


Sujet :

Web & réseau Delphi

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    213
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2002
    Messages : 213
    Points : 109
    Points
    109
    Par défaut [IdTcpServer]Envoi d'objet ou record avec Stream
    Bonjour, vous parait il possible d'envoyer un record contenant des Stream ou un objet via IdTcpClient vers IdTcpServer?

    Voici un lien de mon ancien post demandant +- la même chose, aujourd'hui j'aimerais simplifer la procédure d'envoi de message et envoyer un reocrd complet ou un objet.

  2. #2
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Le seul souci c'est que si on joue avec des pointeur (ie objets, classes) on ne copie via le record que les adresses et non les contenus.

    On est de toute maniere obligé de copier "a la main" les property des classes, les contenu des streams, les valeurs de strings ......

  3. #3
    Membre averti
    Inscrit en
    Novembre 2002
    Messages
    549
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 549
    Points : 436
    Points
    436
    Par défaut
    Dans la FAQ, tu as un excellent exemple de passage de record avec les composants Indy rédigé par notre ami Reisubar

    http://delphi.developpez.com/faq/?pa...0envoyerstruct

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    213
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2002
    Messages : 213
    Points : 109
    Points
    109
    Par défaut
    Citation Envoyé par Clorish Voir le message
    Le seul souci c'est que si on joue avec des pointeur (ie objets, classes) on ne copie via le record que les adresses et non les contenus.

    On est de toute maniere obligé de copier "a la main" les property des classes, les contenu des streams, les valeurs de strings ......
    Aie, en effet, les pointeurs ne sont pas les bienvnus dans l'envoi d'informations

    Citation Envoyé par PpPool Voir le message
    Dans la FAQ, tu as un excellent exemple de passage de record avec les composants Indy rédigé par notre ami Reisubar
    Oui, je l'utilise pour le moment mais le problème c'est que j'envoi plusieurs fichiers et j'aimerais ne faire qu'un seul envoie afin de faciliter la compréhension.

    Comment pourrais je inclure des stream dans le record?

  5. #5
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Rien t'empeche de creer un TMemoryStream que tu remplie avec l'enemble des donnes a envoyer, puis envoyer en bloc le stream memoire.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    213
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2002
    Messages : 213
    Points : 109
    Points
    109
    Par défaut
    L'idée me parait excellente!

    Je vais essayer de mettre cela en musique mais j'avoue avoir un peu de mal avec les stream, enfin surtout avec le compréhension au tour du sujet

  7. #7
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Bha les stream c'ets pas compliqué en fait.
    Imagine ca comme un simple tableau d'octets (byte) dynamqiue.

    Tu as un integer (4 octets) ? ben copier ton integer dans ce "tableaux" a partir de l'indice "10" reviens a occupper les indiche 10, 11, 12, et 13 avec le contenu de l'integer.

    Un autre entier suivant celui ci sera donc stocké des indices 14 a 17.

    Sinon pour manipuler un TStream (il en exite plusieurs sorte : TMemoryStream, TFileStream, TStringStream) i lfaut connaitre peu de choses :

    Position : indice courrant dasn le "tableau" c'est a partir de cet indice que sera ecrit les prochaines donnees (quitte a ecraser des donnees)
    Size : Taille du "tableau". Elle augmente au fure et a mesure qu'on ecrit, en fonction de ce qu'on ecrit. LA reduire, supprime des donner qui depasse, l'augementer permet de "pre-alouer" de l'espace memoire rempli avec du vide.
    Write/Read : ecrit/lit une donnée. le parametre size permet de savoir combent on lit/ecrit d'octets. Exemple : Read(IntValue, SizeOf(Integer))
    Seek : permet de se deplacer dans le fichier. Equivalent a une affectation de position. le 2e parametre permet de se deplacer du debut, de la fin ou de la position courrante ...
    CopyFromStream : Permet de copier N bits d'un stream dans un autre a aprtir de Position (dans les 2 stream). S'assurer de la bonne valeur de "position".

    Pour plus d'infos, ... n'hesite pas

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    213
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2002
    Messages : 213
    Points : 109
    Points
    109
    Par défaut
    Je te remercie pour tes infos complè!te qui m'ont bien éclairée et permis d'avancer un peu

    Maintenant je me retrouve bloqué une étape plus loin ... j'essaye de copier mon record en mémoire et le récupérer par une autre fonction mais visiblement la copie en mémoire s'effectue mal et je récupère un stream vide de l'autre côté (ou bien un message d'erreur, ce qui me parait logique vu que j'essaye des informations qui n'existent pas, correct?)

    Voici la structure de mon record (mis à part les 2 stream, les tailles sont fixe) :
    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
     
    type
      TRaytracer = record
        Login : String[7];
        Height : Integer;
        Width : Integer;
        FileName : String[20];
        Extension : String[3];
        CameraView : String[20];
        RenderMode : Integer;
        ProjectionMode : Integer;
        DateCreation : String[8];
        HStart : String[11];
        HEnd : String[11];
        FmlFiles, EnvFiles : TStream;
        FmlSize, EnvSize: integer;
    end;
    Voici l'objet qui controle le record (pas frapper pour sa définition, je suis au début mon appretissage OO :o) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      TControlRaytracer = class
      public
        Raytracer : TRaytracer;
        StreamSize : Int64;
      published
        procedure SetOfmlFiles(Filename:String);
        procedure SetResolution(Resolution:String);
        function WriteToStream:TMemoryStream;
        procedure ReadFromStream(RayTMemoryStream : TMemoryStream;Size:integer);
      end;
    Voici la fonction que j'utilise pour copier le record dans un TMemoryStream :
    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
     
    function TControlRaytracer.WriteToStream:TMemoryStream;
    var
      RayTMemoryStream : TMemoryStream;
    begin
     
      RayTMemoryStream := TMemoryStream.Create;
      try
        RayTMemoryStream.Write(Raytracer,SizeOf(Raytracer));
     
        RayTMemoryStream.Write(Raytracer.login,SizeOf(Raytracer.login));
        RayTMemoryStream.Write(Raytracer.Height,SizeOf(Raytracer.Height));
        RayTMemoryStream.Write(Raytracer.Width,SizeOf(Raytracer.Width));
        RayTMemoryStream.Write(Raytracer.FileName,SizeOf(Raytracer.FileName));
        RayTMemoryStream.Write(Raytracer.Extension,SizeOf(Raytracer.Extension));
        RayTMemoryStream.Write(Raytracer.CameraView,SizeOf(Raytracer.CameraView));
        RayTMemoryStream.Write(Raytracer.RenderMode,SizeOf(Raytracer.RenderMode));
        RayTMemoryStream.Write(Raytracer.ProjectionMode,SizeOf(Raytracer.ProjectionMode));
        RayTMemoryStream.Write(Raytracer.DateCreation,SizeOf(Raytracer.DateCreation));
        RayTMemoryStream.Write(Raytracer.HStart,SizeOf(Raytracer.HStart));
        RayTMemoryStream.Write(Raytracer.HEnd,SizeOf(Raytracer.HEnd));
     
        RayTMemoryStream.Write(Raytracer.FmlFiles,Raytracer.FmlSize);
        RayTMemoryStream.Write(Raytracer.EnvFiles,Raytracer.EnvSize);
     
        StreamSize := RayTMemoryStream.Size;
     
        Result := RayTMemoryStream;
     
      finally
        FreeAndNil(RayTMemoryStream);
      end;
     
    end;
    Et pour finir, la fonction que j'utilise pour lire le Stream :
    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
     
    procedure TControlRaytracer.ReadFromStream(RayTMemoryStream : TMemoryStream;Size:integer);
    begin
     
        RayTMemoryStream.Position := 0;
        RayTMemoryStream.Read(Raytracer,SizeOf(Size));
        ShowMessage(inttostr(RayTMemoryStream.Size));
     
        RayTMemoryStream.Read(Raytracer.login,SizeOf(Raytracer.login));
        RayTMemoryStream.Read(Raytracer.Height,SizeOf(Raytracer.Height));
        RayTMemoryStream.Read(Raytracer.Width,SizeOf(Raytracer.Width));
        RayTMemoryStream.Read(Raytracer.FileName,SizeOf(Raytracer.FileName));
        RayTMemoryStream.Read(Raytracer.Extension,SizeOf(Raytracer.Extension));
        RayTMemoryStream.Read(Raytracer.CameraView,SizeOf(Raytracer.CameraView));
        RayTMemoryStream.Read(Raytracer.RenderMode,SizeOf(Raytracer.RenderMode));
        RayTMemoryStream.Read(Raytracer.ProjectionMode,SizeOf(Raytracer.ProjectionMode));
        RayTMemoryStream.Read(Raytracer.DateCreation,SizeOf(Raytracer.DateCreation));
        RayTMemoryStream.Read(Raytracer.HStart,SizeOf(Raytracer.HStart));
        RayTMemoryStream.Read(Raytracer.HEnd,SizeOf(Raytracer.HEnd));
     
     
        RayTMemoryStream.Read(Raytracer.FmlFiles,Raytracer.FmlSize);
        RayTMemoryStream.Read(Raytracer.EnvFiles,Raytracer.EnvSize);
     
    end;
    Et pour finir, voici le code que j'utilise pour copier mon record en mémoire (RayMemory et RaySize sont des variables globales à ma form) :
    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
     
    var
      TestRayT : TControlRaytracer;
    begin
     
      try
     
        TestRayT := TControlRaytracer.Create;
     
        TestRayT.Raytracer.Login := 'dli0108';
        TestRayT.Raytracer.Height := 640;
        TestRayT.Raytracer.Width := 480;
        TestRayT.Raytracer.FileName := 'test';
        TestRayT.Raytracer.Extension := 'jpg';
        TestRayT.Raytracer.CameraView := '1';
        TestRayT.Raytracer.RenderMode := 1;
        TestRayT.Raytracer.ProjectionMode := 1;
        TestRayT.Raytracer.DateCreation := '5';
        TestRayT.Raytracer.HStart := '';
        TestRayT.Raytracer.HEnd := '';
        TestRayT.SetOfmlFiles(OpenDialog.FileName);
     
        RayMemory := TestRayT.WriteToStream;
        RaySize := TestRayT.StreamSize;
      finally
        FreeAndNil(TestRayT);
      end;
    Et pour la toute dernière, la tentative de récupération du record (et copie dans un memo) :
    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
     
    var
      TestRayT : TControlRaytracer;
    begin
     
      try
        TestRayT := TControlRaytracer.Create;
        TestRayT.ReadFromStream(RayMemory,RaySize);
        Memo1.Lines.Add(TestRayT.Raytracer.Login);
        Memo1.Lines.Add(TestRayT.Raytracer.FileName);
        Memo1.Lines.Add(TestRayT.Raytracer.Extension);
        Memo1.Lines.Add(TestRayT.Raytracer.CameraView);
        Memo1.Lines.Add(TestRayT.Raytracer.Login);
        Memo1.Lines.Add(IntToStr(TestRayT.Raytracer.Height));
        Memo1.Lines.Add(IntToStr(TestRayT.Raytracer.Width));
     
      finally
        FreeAndNil(TestRayT);
      end;

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    213
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2002
    Messages : 213
    Points : 109
    Points
    109
    Par défaut
    Voilà, j'ai enfin réussi à utiliser les stream, ouf!

    J'avoue que par contre que c'est a taton que j'ai réussi et après pas mal d'essai
    Ma compréhension est nettement meilleur sur le sujet mais je suis loin d'en comprendre toute les ficèles, cela viendra avec le temps je suppose

    Le plus grops point ou j'ai du mal, c'est quand il faut allouer la taille dans le stream, faut il utiliser SizeOf ou pas

    Dès que j'ai un peu de temps, je mets les fonctions à jour pour ceux qui seraient intéressé ultérieurement.

    Merci de ton aide Clorish

  10. #10
    Membre expérimenté

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    Je pense sinon qu'il y a plus simple :

    1. Ecrire le record (sans le stream). L'enregistrement a une taille fixe, il peut être directement transmis dans un TIdBuffer.
    2. Ecrire le stream. Indy a des fonctions de lecture/écriture sur les flux (ReadStream/WriteStream) intégrées.

    Mais bon, si le code courant marche ;-)

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    213
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2002
    Messages : 213
    Points : 109
    Points
    109
    Par défaut
    C'est exactement ce que je faisais avant, mais comem il est possible que d'autres fichiers viennent se rajouter, je veux simplifier les échanges au minimum

Discussions similaires

  1. Problème d'envoi d'objets au serveur avec gson
    Par Karly dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 23/07/2012, 02h48
  2. Réponses: 0
    Dernier message: 19/03/2010, 18h33
  3. Envoi d'objet avec une socket
    Par HamzuS The Great dans le forum VB.NET
    Réponses: 4
    Dernier message: 06/09/2009, 16h09
  4. Pb d'envoie de mail en ASP avec un objet CDO
    Par mister_rom dans le forum ASP
    Réponses: 1
    Dernier message: 02/04/2007, 23h56
  5. Envoi de messages MS DOS avec le IP
    Par asphp dans le forum Développement
    Réponses: 6
    Dernier message: 07/01/2004, 17h11

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