Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Dateien über TCP (https://www.delphipraxis.net/8863-dateien-ueber-tcp.html)

Meflin 13. Sep 2003 18:46


Dateien über TCP
 
weis jemand, wie man dateien über tcp/ip
versenden kann(also mit der indy compo).
wie man text übermittelt weis ich ja, aber dateien?
muss ich da nen filestream erstellen und wie geht das dann?

*MFG & THX*

OrallY 13. Sep 2003 20:24

Re: Dateien über TCP
 
Jo, n Filestream ist schon mal eine gute Idee. Und die TCP-Kompos von Indy haben die netten Methoden WriteStream und ReadStream. D.h. also, dass du zuerst die Datei in den Filestream einliest und diesen dann mit WriteStream verschickst. Auf der anderen Seite ebenfalls ein Filestream und mit ReadStream empfangen. Fedisch.
Kann dir morgen auch mal ein Beispiel posten, wenn du nicht klarkommst.

Meflin 14. Sep 2003 09:53

Re: Dateien über TCP
 
wer nett wenn du ein beispiel posted,
dann check ichs leichter!
ich mein das prinzip hab ich schon kapiert
aber es würde mir helfen!

*MFG*

OrallY 14. Sep 2003 17:48

Re: Dateien über TCP
 
Ich hab jetzt mal ein Beispiel zusammengeackt, doch zu meinem Erstaunen funktioniert es nicht :?. Ich bekomme bei der ReadStream-Methode einen EReadError "Stream read error". Kann jetzt mir einer weiterhelfen? :|
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  fs: TFileStream;
begin
  if not OpenDialog1.Execute then exit;
  with IdTCPClient1 do
  begin
    fs := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyWrite);
    Connect;
    try
      WriteStream(fs);
    finally
      Disconnect;
      fs.Free;
    end;
  end;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
  fs: TFileStream;
begin
  if not SaveDialog1.Execute then exit;
  fs := TFileStream.Create(SaveDialog1.Filename, fmCreate or fmShareExclusive);
  with AThread.Connection do
    try
      ReadStream(fs);
    finally
      Disconnect;
      fs.Free;
    end;
end;

Stevie 17. Sep 2003 09:17

Re: Dateien über TCP
 
Hi OrallY!

Da ich auch schon an dieser Sache versucht hab und gescheitert bin, bin ich dir erstmal dankbar für den Tip. Also, ich hab den Code noch etwas ergänzt, weil ich festgestellt hab, dass der Stream bei mir ca. 1,6 GB groß war, obwohl ich eine 2KB-Datei genommen hab. Das gab Probleme bei speichern, weil ich nicht mehr soviel Platz auf der Festplatte hatte (sonst hätte ich den Fehler vielleicht garnicht gefunden). Ich hab einfach mal die Größe der Datei vorweggeschickt; ich hab WriteLn bzw ReadLn benutzt, weil manchmal WriteInteger und ReadInteger Fehler macht, wenn die folgenden Daten auch als Integer ausgewertet werden könnten.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  fs: TFileStream;
begin
  if not OpenDialog1.Execute then exit;
  with IdTCPClient1 do
  begin
    fs := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyWrite);
    Connect;
    try
      WriteLn(IntToStr(fs.Size));
      WriteStream(fs);
    finally
      Disconnect;
      fs.Free;
    end;
  end;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
  fs: TFileStream;
  size: Longint;
begin
  if not SaveDialog1.Execute then exit;
  fs := TFileStream.Create(SaveDialog1.Filename, fmCreate or fmShareExclusive);
  with AThread.Connection do
    try
      size := StrToInt(ReadLn);
      ReadStream(fs, size);
    finally
      Disconnect;
      fs.Free;
    end;
end;
Ach, und vergess nicht SendBufferSize(in Byte) des TCPClients auf eine Größe zu setzen, die mindestens so groß ist, wie die Datei, die du versenden möchtest.

OrallY 17. Sep 2003 16:24

Re: Dateien über TCP
 
Danke, Stevie, du hast mich auf die Idee gebracht. Mir ist gerade wieder ein Parameter von WriteStream eingefallen der das, was du gemacht hast, von selbst erledigt. Und zwar AWriteByteCount. Wenn dieser true ist, wird die Größe des Streams nämlich automatisch mit WriteInteger (mal nebenbei, WriteInteger hättest du auch verwenden können :chat: :angle2: ) verschickt. Nun muss man nur noch vor der ReadStream Methode die Größe mit ReadInteger abfangen und ReadStream als Parameter übergeben. Bingo.

Die Größe von SendBufferSize zu verändern nützt reichlich wenig, zumahl die Maximalgröße bei 32768 Bytes liegt. Diese Eigenschaft gibt nur an, wieviel Bytes (maximal) immer auf einmal gesendet werden.
Also, der Finale Code:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  fs: TFileStream;
begin
  if not OpenDialog1.Execute then exit;
  with IdTCPClient1 do
  begin
    fs := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyWrite);
    Connect;
    try
      OpenWriteBuffer;
      try
        WriteStream(fs, true, true, 0); //das 2. true ist das entscheidende
        CloseWriteBuffer;
      except
        CancelWriteBuffer;
        raise;
      end;
    finally
      Disconnect;
      fs.Free;
    end;
  end;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
  fs: TFileStream;
  SizeOfIncomingStream: integer;
begin
  if not SaveDialog1.Execute then exit;
  fs := TFileStream.Create(SaveDialog1.Filename, fmCreate or fmShareExclusive);
  with AThread.Connection do
    try
      SizeOfIncomingStream := ReadInteger;
      ReadStream(fs, SizeOfIncomingStream);
    finally
      Disconnect;
      fs.Free;
    end;
end;
Also nochmal vielen Dank Stevie! :)

Spurius 1. Mär 2004 13:43

Re: Dateien über TCP
 
Der Thread ist zwar schon älter aber ich hab ne Frage dazu, und zwar wie kann ich auf den Stream zugreifen der empfangen wird? Er wird ja mit ReadStream vom Server empfangen, aber wie kann ich ich dann aus dem stream lesen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz