![]() |
Re: Indy-TCP-Server aufsetzen und Dateien versenden
Dieser Beitrag stand ursprünglich in Zusammenhang mit diesem Tutorial:
![]() 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:
Der Server:
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;
Delphi-Quellcode:
Und dann wieder beim Clienten:
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))) = 'DATA' then 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;
Delphi-Quellcode:
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.
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 ='DATA' then 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 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] |
Re: Dateiversand zwischen Chatclients (Indy)
Hallo,
Du musst dem Server mitteilen, wie groß die Datei ist, die da verschickt wird! Ich habe das so gelöst:
Delphi-Quellcode:
Erklärung:
...
IdTcpClient1.WriteInteger(4); IdTcpClient1.WriteLn(sMsgToSvr); IdTcpClient1.WriteInteger(SendSize); idTCPClient1.OpenWriteBuffer; idTcpClient1.WriteStream(fs, False, False, SendSize); idTCPClient1.CloseWriteBuffer; ... 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:
Auch hier wird erst wieder die Größe der zu empfangenden Datei festgestellt...
...
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; ... Ach ja, hier die Behandlung der Datei durch den Server und den Versand an alle Clients (im TCPServer.Execute):
Delphi-Quellcode:
Edit:
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; Ein wenig ausführlicher habe ich das Ganze nun in folgenden Thread ausgeführt: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz