AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Dateiversand zwischen Chatclients (Indy)
Thema durchsuchen
Ansicht
Themen-Optionen

Dateiversand zwischen Chatclients (Indy)

Ein Thema von night · begonnen am 17. Okt 2008 · letzter Beitrag vom 20. Okt 2008
Antwort Antwort
night

Registriert seit: 23. Jun 2006
22 Beiträge
 
Turbo Delphi für Win32
 
#1

Re: Indy-TCP-Server aufsetzen und Dateien versenden

  Alt 17. Okt 2008, 16:53
Dieser Beitrag stand ursprünglich in Zusammenhang mit diesem Tutorial:
Indy-TCP-Server aufsetzen und Dateien versenden



Hi,der Beitrag ist schon etwas älter, passt aber zu meinem Thema.
Hier wurde gezeigt, wie man vom Client eine Datei zum Server schicken kann. Ich möchte aber nun eine Datei von einem Client zum anderen schicken.
Ich habe mir dazu folgendes überlegt, bzw von oben übernommen:

Client:
Delphi-Quellcode:
if OpenDialog1.Execute then
    begin
      //Data= Befehl; Receiver = an wen die Datei geht und Dateiname
      Msg := '!DATA~'+receiver+'~'+OpenDialog1.FileName;
      FTCPClient.WriteLn(MSG);
      FileStream := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyNone);
      try
        MyFileSize := FileStream.Size;
        while MyFileSize > 0 do
        begin
          SendSize := MyFileSize;
          if SendSize > 1024 then
            SendSize := 1024;
          Dec(MyFileSize, SendSize);
        FTcpClient.WriteStream(FileStream, False, False, SendSize);
      end;
      finally
       FileStream.Free;
      end;
    end;
Der Server:
Delphi-Quellcode:
procedure TForm1.tcpServerExecute(AThread: TIdPeerThread);
var Msg: String;
    receiver: String;
    MyFileName: String;
    FileStream: TFilestream;
    list: TList;
    MyFileSize: int64;
begin
  msg := AThread.Connection.ReadLn;
  if Msg[1] = '!then
  begin
   Msg := Trim(Copy(Msg, Pos('!', Msg) +1, Length(Msg)));
   if Trim(Copy(Msg, Pos('!', Msg) +1, Pos('~', Msg))) = 'DATAthen
   begin
    Msg := Trim(Copy(Msg, Pos('~', Msg) +1, length(Msg)));
    Receiver := Trim(Copy(Msg,1, Pos('~', Msg)));
    MyFileName := Trim(Copy(Msg, Pos('~', Msg) +1, length(Msg)));
      
    FileStream := TFileStream.Create(MyFileName, fmCreate);
    try
      AThread.Connection.ReadStream(FileStream, MyFileSize);
      List := FtcpServer.Threads.LockList;
      try
       msg := '!DATA~';
TIdPeerThread(List.Items[ListBox_Server_Clients.Items.IndexOf(Receiver)]).Connection.WriteLn(msg); TIdPeerThread(List.Items[ListBox_Server_Clients.Items.IndexOf(Receiver)]).Connection.WriteStream(FileStream, False, False, Filestream.Size);
      finally
        FtcpServer.Threads.UnlockList;
      end;
    finally
      FileStream.Free;
    end;
   end
  end;
end;
Und dann wieder beim Clienten:
Delphi-Quellcode:
procedure TForm1.ReceiveMessage;
var Msg: String;
    command: String;
    FileStream: TFilestream;
    MyFileSize: int64;
begin
  if FTcpClient.Connected then
  begin
    if (Msg[1] = '!') then
    begin
        command := (Trim(Copy(Msg, Pos('!', Msg)+1, Pos('~', Msg) -2)));
        if command ='DATAthen
        begin
          if SaveDialog1.Execute then
          begin
            FileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate);
            try
              FTCPClient.ReadStream(FileStream, MYFileSize);
            finally
              FileStream.Free;
            end;
           end;
        end;
      end
   end;
end;
Ich will damit einen bestehenden Chat, den ich letztes Jahr gemacht habe, um einen Filetranfer erweitern und habe alles Coding, das nichts damit zu tun hat rausgeschmissen(deswegen kann evt ein "end" zu viel oder zu wenig sein . Leider hängt sich mein Programm auf.
Ich selbst habe bis jetzt nur einfache Nachrichten verschickt (Indy 9) und befinde mich hier auf Neuland. Für Denkanstöße oder Beispiele wäre ich dankebar.

Viele Grüße
Stefan

[edit=fkerber]Thread geteilt, da eigenständige Frage. Mfg, fkerber[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von hincapie
hincapie

Registriert seit: 24. Mär 2005
200 Beiträge
 
Delphi 5 Professional
 
#2

Re: Dateiversand zwischen Chatclients (Indy)

  Alt 20. Okt 2008, 08:47
Hallo,
Du musst dem Server mitteilen, wie groß die Datei ist, die da verschickt wird!
Ich habe das so gelöst:
Delphi-Quellcode:
...
  IdTcpClient1.WriteInteger(4);
  IdTcpClient1.WriteLn(sMsgToSvr);
  IdTcpClient1.WriteInteger(SendSize);
  idTCPClient1.OpenWriteBuffer;
  idTcpClient1.WriteStream(fs, False, False, SendSize);
  idTCPClient1.CloseWriteBuffer;
...
Erklärung:
In der ersten Zeile wird per Kommando dem Server mitgeteilt, was er machen sollen, ähnlich dem '!' in Deinem Code.
Danach kommt der Dateiname (sMsgToSvr), danach (wichtig!) die Dateigröße (SendSize) ...

dann der Empfang der Datei:
Delphi-Quellcode:
...
      if Msg[1] = '#then //send files
      begin
        msg2 := Copy(Msg, 2, Length(Msg));
        if FileExists(ProgDir + Msg2) then
          DeleteFile(ProgDir + Msg2);
        ftmpStream := TFileStream.Create(ProgDir + Msg2, fmCreate or fmShareDenyNone);
        try
          try
            //while IdTCPClient1.connected do
            FileSize := IdTCPClient1.ReadInteger();
            IdTCPClient1.ReadStream(fTmpStream, FileSize, False); //-1,true);
            Log(100, 'File ' + Msg2 + ' with ' + IntToStr(FileSize) + ' kbs received!');
            PostMessage(avatar, 'File ' + Msg2 + ' with ' + IntToStr(FileSize) + ' kbs received!');
            Application.ProcessMessages;
          except
            Log(101, 'Error on filetransfer!');
            exit;
          end;
        finally
          FreeAndNil(fTmpStream);
        end;
      end;
...
Auch hier wird erst wieder die Größe der zu empfangenden Datei festgestellt...



Ach ja, hier die Behandlung der Datei durch den Server und den Versand an alle Clients (im TCPServer.Execute):
Delphi-Quellcode:
    Cmd := AThread.Connection.ReadInteger;
    if cmd = 4 then
    begin
      try
        try
          Msg := AThread.Connection.ReadLn;
          FileName := Msg;
          CS := TCriticalSection.Create;
          CS.Enter;
          sMsgToClt := '#' + FileName;
          ts := TMemoryStream.Create;
          FileSize := AThread.Connection.ReadInteger();
          AThread.Connection.ReadStream(ts, FileSize, False);
          Log(Format('Getting client upload %5d, %s', [FileSize, FileName]));
          List := TcpServer.Threads.LockList;
          try
            for Count := 0 to List.Count -1 do
            try
              TIdPeerThread(List.Items[Count]).Connection.WriteLn(sMsgToClt);
              TIdPeerThread(List.Items[Count]).Connection.WriteInteger(FileSize);
              TIdPeerThread(List.Items[Count]).Connection.OpenWriteBuffer;
              TIdPeerThread(List.Items[Count]).Connection.WriteStream(ts, True, False, FileSize);
              TIdPeerThread(List.Items[Count]).Connection.CloseWriteBuffer;
              Log('File ' + ExtractFileName(FileName) + ' sent to clients!');
            except
              TIdPeerThread(List.Items[Count]).Stop;
              Log('Error while sending file to clients!');
            end;
          finally
            TcpServer.Threads.UnlockList;
            CS.Leave;
          end;
        except
          ShowMessage('Error');
          Log('Error on getting file');
        end;
      finally
        ts.free;
      end;
Edit:
Ein wenig ausführlicher habe ich das Ganze nun in folgenden Thread ausgeführt:
Beispiel zum Versenden von Dateien mit Indy
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:33 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