Einzelnen Beitrag anzeigen

Benutzerbild von hincapie
hincapie

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

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