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 :

[TcpServer] problème d'envoi d'un record et d'un fichier vers un serveur


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 [TcpServer] problème d'envoi d'un record et d'un fichier vers un serveur
    Bonjour,

    je débute dans la programmation client/server et j'aimerai envoyer à la fois 1 record et 2 fichiers vers mon server.
    Le problème, c'est que j'arrive à envoyer de manière individuelle mon record ou un fichier, mais dès que j'essaye de faire les 2 en même temps (l'un a la suite de l'autre mais dans la même routine), cela ne fonctionne pas la connexion se coupe automatiquement.

    J'ai regardé un peu partout sur le net, visiblement, la solution des command handlers me conviendrait parfaitement mais c'est uniquement pour une solution texte

    Quelqu'un a t'il un solution pour moi? (si le problème est clairement expliqué ...)
    Mais quelle bordel !

  2. #2
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Suggestion qui vaut ce qu'elle vaut si tu arrive à envoyer un fichier :

    Algorithme Coté source :
    1) tu enregistres ton record dans un fichier temporaire (style fichier ini ou bien fichier binaire)
    2) tu crées un autre fichier temporaire avec un composant comme TBackupFile (Composant gratuit d'archivage qui se trouve ici : http://www.torry.net/quicksearchd.ph...ckup&Title=Yes)
    Dans ce fichier tu y place le fichier que tu as créé en 1) et tes deux fichiers.
    3)Tu envoies ton fichier backup.
    4) tu effaces les deux fichiers temporaires.

    Algorithme coté destinataire, à la réception :
    1) tu reçois le fichier backup
    2) tu le décompresse en plaçant les trois fichiers où tu veux
    3) tu lis le fichier ini (ou binaire) temporaire que tu viens d'extraire pour alimenter ton record.
    4) tu efface le fichier backup réceptionné du disque dur, ainsi que ton fichier binaire.

    Je crois que tu devrais y arriver. TBackFile est TRES bien documenté et TRES simple à utiliser.

    Bon dev.
    Bidouilleuse Delphi

  3. #3
    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
    Merci pour ta solution qui en effet pourrait convenir mais j'aimerai surtout comprendre comment cela fonctionne.
    Ce qui me permettrait lors de futures (possibles) mises à jours de ne pas devoir réécrire tout le fichier backup à renvoyer
    Mais quelle bordel !

  4. #4
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    En fait, le fichier backup créé avec le composant que je t'ai indiqué est en fait une espèce de fichier zip que chronologiquement.
    1) tu crée
    2) puis envoies,
    3) puis réceptionnes,
    4) puis utilises;

    Pour le creer :
    1) tu lui fourni dans un tstringlist, une liste de fichier
    2) tu utilises la méthode Backup du composant.

    Pour extraire les fichiers, tu as une methode restore, qui te permet d'extraire tes fichiers où tu veux (il y a un évènement OnRestoreFile pour ça).

    Les deux méthodes et comment les utiliser sont hyper bien expliqué dans le fichier d'aide joint au composant.

    Normalement tu devrais t'en sortir avec une vingtaine de lignes de code tout au plus (et encore).

    Donc tu vois, pas besoin de réécrire le fichier backup, seul la construction de la liste de fichiers est à modifier dans le client, et l'endroit ou tu décompresse le tout dans le serveur.


    Si tu veux savoir comment le compo fonctionne, télécharges le, installes-le et jettes toi sur le fichier hlp qui viens avec, c'est très simple et très limpide.

    Je te fait des copier-coller de l'aide :
    Pour creer le fichier backup :



    Starts the backup operation and returns true, if successful.

    function Backup(const Filelist: TStrings; Target: string): boolean;

    Description
    The constant Filelist must contain the full path names and the file names or wildcards.
    Example - this is a valid list of files:

    c:\program files\myprogram\myprog.exe
    c:\program files\myprogram\data\*.db
    c:\program files\myprogram\data\*.xg?
    c:\program files\myprogram\data\*.yg?


    If you want to include all files in a directory, you must specify the wildcards with *.*
    Example:

    c:\program files\myprogram\*.* //all files in this directory

    If you want to include all files in a directory including all files in all its sub-directories, add a /s to the file mask. Example:

    c:\program files\myprogram\*.* /s
    //include all subdirectories as well


    Target must point to a valid archive file name. The archive is created - if an archive with the same name exists, it is overwritten without commitment. There are no rules for the file extension of the archive.

    If TBackupFile needs to split the archive on multiple disks, the extension of the archive file changes to ".002" for the second disk, ".003" for the third and so on.

    Examples:

    a:mybackup.bck
    a:\backup_from_today.xyz
    c:\program files\myprogram\backupdir\mybackup.001


    Example to execute a backup:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    backupfile1.backup( listbox1.items, 'A:backup.bck');
    Un exemple Pour récupérer les fichiers :
    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
     
    ...
      backupfile1.restore('a:backup.bck', 'c:\program files\myprogram\data\');
    ...
     
    procedure TForm1.BackupFile1RestoreFile(Sender: TObject;   
         var Filename: string; var DoRestore: Boolean);
    begin
       if extractFileExt(filename) = '.dat' then 
         Filename := MyDataPath + ExtractFilename(filename)
       else
         Filename := MyProgPath + ExtractFilename(filename);
     
       DoRestore := extractFileExt(filename) <> '.tmp';
    end;
    Tu vois ce n'est pas bien sorcier !!! donc pour mettre à jour ton programme par la suite, ça doit être assez facile.

    Sinon, si tu veux envoyer des "backup" de nature différente, tu peux donner un titre à tes archives au moment de les créer (propriété Title),
    à la réception tu traite le fichier reçu en fonction du titre du backup reçu.

    Sinon, qu'est ce que tu n'a pas compris ?
    Bidouilleuse Delphi

  5. #5
    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 ta réponse plus que complète !

    Mais je suis assez tetu et je voulais vraiment comprendre ce qui ne fonctionnait pas dans ma fonction et à force de chercher, j'ai trouvé

    Un grand merci quand même pour ton aide

    Pour ceux qui sont interessé, voici le code client et serveur.
    J'envoie donc un record et ensuite un fichier au serveur.

    Client
    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
     
    type
      TRaytracer = record
        Height : Integer;
        Width : Integer;
        PictureName : String[20];
        FileName : String[20];
        Extension : String[3];
        CameraView : String[20];
        RenderMode : Integer;
        ProjectionMode : Integer;
    end;
    ...
    procedure TForm1.Button2Click(Sender: TObject);
    var
      RayT : TRaytracer;
      Rbuffer : TIdBytes;
      LCommand, LInString : String;
      FsStream : TIdStreamVCL;
     
    ...
     
      with IdTCPClient1 do
      begin
        try
          SetLength(Rbuffer, SizeOf(RayT));
          Move(RayT, Rbuffer[0], SizeOf(RayT));
          {Envoyer...}
          IdTCPClient1.IOHandler.WriteLn('RECORD ');
          IdTCPClient1.IOHandler.Write(RawToBytes(RayT, SizeOf(RayT)));
     
          ShowMessage(IOHandler.ReadLn);
     
          FsStream := TIdStreamVCL.Create(TFileStream.Create(OpenDialog.FileName,fmOpenRead),True);
          IdTCPClient1.IOHandler.WriteLn('FILE ');
          IOHandler.Write(FsStream.VCLStream.Size);
          IOHandler.Write(FsStream,0);
          FreeAndNil(FsStream);
     
          LInString := IOHandler.ReadLn;
     
          Label1.Caption := 'We Send -> ' + LCommand + ' - Server Send -> ' + LInString;
     
          except
          on E : Exception do
            ShowMessage(E.Message);
          end;
      end;
    Server
    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
     
    procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
    var
      RayT : TRaytracer;
      RBuffer : TIdBytes;
      str, Line : String;
      i, ByteCount : Integer;
      Fs : TFileStream;
      FsStream : TIdStreamVCL;
    begin
     
      Line := AContext.Connection.IOHandler.ReadLn(); //Attends une commande de la forme TRANS suivi du nom de fichier
      i := Pos(' ',Line);
      if (i>0) and (LowerCase(Copy(Line,1,Pred(i)))='record') then
      begin
        {Définir la taille du buffer}
        SetLength(RBuffer, SizeOf(RayT));
        {Lire}
        AContext.Connection.IOHandler.ReadBytes(RBuffer, SizeOf(RayT), False);
     
        Move(RBuffer[0],RayT,SizeOf(RayT));
        Memo1.Lines.Add(IntToStr(RayT.Height));
        Memo1.Lines.Add(IntToStr(RayT.Width));
        Memo1.Lines.Add(RayT.FileName);
        Memo1.Lines.Add(RayT.Extension);
        Memo1.Lines.Add(RayT.CameraView);
        Memo1.Lines.Add(IntToStr(RayT.RenderMode));
        AContext.Connection.IOHandler.WriteLn(RayT.FileName + 'Record');
      end;
     
      Memo1.Lines.Add('');
     
      Line := AContext.Connection.IOHandler.ReadLn(); //Attends une commande de la forme TRANS suivi du nom de fichier
      i := Pos(' ',Line);
      if (i>0) and (LowerCase(Copy(Line,1,Pred(i)))='file') then
      begin
        ShowMessage('file');
     
        ByteCount := AContext.Connection.IOHandler.ReadInt64();
     
        FsStream := TIdStreamVCL.Create(TFileStream.Create('d:\test.pov',fmCreate),True);
        try
          AContext.Connection.IOHandler.ReadStream(FsStream,ByteCount);
          Memo1.Lines.Add(IntToStr(ByteCount));
        finally
          FreeAndNil(FsStream);
        end;
        AContext.Connection.IOHandler.WriteLn('Fichier envoyé File');
      end;
     
    end;
    Le code est un copié/collé de la FAQ sur Indy 10
    Mais quelle bordel !

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

Discussions similaires

  1. Envoi fichier vers un serveur en https
    Par new70 dans le forum Unix
    Réponses: 2
    Dernier message: 16/01/2015, 13h21
  2. Envoi de oordonnées à partir d'une application Android vers un serveur IIS
    Par saidasahraouiya dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 16/01/2014, 17h27
  3. Envoi d'une chaîne d'un client PHP vers un serveur en C
    Par barnabe87 dans le forum Débuter
    Réponses: 4
    Dernier message: 20/01/2011, 15h28
  4. Envoi d'un fichier vers un serveur FTP
    Par mouloudéen dans le forum VB.NET
    Réponses: 3
    Dernier message: 01/04/2010, 11h52
  5. [HTML] Problème d'envoi de formulaire
    Par autumn319 dans le forum ASP
    Réponses: 26
    Dernier message: 03/09/2003, 10h06

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