Re: indy10 / TCPServer /TCPClient ->Datei versenden
Ich weiß nicht, ob es in diesem Fall nützlich ist, aber vor einiger Zeit habe ich mich mal ans Senden per TCP und Indy 10 gemacht, und dazu auch was für die CodeLib aufbereitet. Du findest den Code hier, vielleicht hilft dir ein Teil daraus (Stichwort Stream) weiter :)
|
Re: indy10 / TCPServer /TCPClient ->Datei versenden
Danke für deine schnelle Antwort...
... und wieder sind mir einige Lichter aufgegangen... habe aber leider immer noch div. Probleme... Also, was ich will ist erstmal folgendes... - Programm#1 will Programm#2 eine Datei schicken. Und sendet (cmd 1) an Prg#2 - Programm#2 erhält den Command 1 (jmd will datei senden) - Programm#2 akzeptiert (cmd 2) oder lehnt Datei ab (cmd 3) - Programm#1 wenn Prg#1 (cmd 2) erhält versucht es Datei an Prg#2 zu senden. Wenn (cmd 3) dann abbrechen. Dabei ist Programm#1 und Programm#2 genau dasselbe... läuft einfach auf unterschiedlichen Rechnern... Die Programm sollen die Informationen so austauschen, dass das andere immer weiss was das andere macht. Wenn ich das jetzt so mache wie du mir vorschlägst:
Delphi-Quellcode:
Dann überschreibts ja immer gleich tmpClient.LastCmd...
.. try
// Daten im Buffer ? tmpClient.LastCmd := AContext.Connection.Socket.ReadLn(#$A,Settings.CmdReadTimeOut,Settings.CmdMaxLength); except tmpClient.LastCmd := ''; end; // Da das OnExecute des Server immer wieder eintritt bis der Client nicht mehr verbunden ist kann der obere Teil als // allgemeingültig bezeichnet werden. Je nach empfangenen Daten/Kommando jetzt weiter vorgehen // z.B. Case tmpClient.LastIntCommand of // end; // oder if tmpClient.LastCmd = 'YXZ' then begin end; // ... Wie kann ich nun z.B. den Namen der Datei schicken?! usw. Es müsste ja irgendwie möglich sein zuerst einen befehl zu schicken und dann noch weitere Parameter z.b. Filename... oder dann beim uploaden den befehl z.b (cmd 2) für upload und dann den stream... Irgendwo hab ich noch ne grosse lücke! Gruss |
Re: indy10 / TCPServer /TCPClient ->Datei versenden
Allen vielen Dank für eure Hilfe...
Fürs erste hab ichs nun hinbekommen, scheint jedenfalls zu funktionieren. Eine kleine Frage hätte ich da aber noch, wie kann man nun die Progressbar des "uploaders" (TCPServer) anzeigen lassen? hier mein aktueller code:
Delphi-Quellcode:
und
// SEND FILE / ACCEPT INCOMMING FILE (same button)
procedure TForm1.EButton2Click(Sender: TObject); begin if EButton2.Caption = 'upload' then begin if OpenDialog1.Execute then begin try uploadfilepath := OpenDialog1.FileName; EButton2.Enabled := False; EButton5.Enabled := False; TCPClient.Connect; // upload file TCPSendCmd(CmdUploadFile); TCPClient.IOHandler.WriteLn(ExtractName(uploadfilepath)); Log(msg001); Log('wait for client reply...'); except on e:Exception do begin Log(e.Message); EButton2.Enabled := True; end; end; end; end else begin try ButtonCaption('receive'); EButton2.Enabled := False; EButton4.Enabled := False; EButton5.Enabled := False; TCPClient.Connect; // accept file TCPSendCmd(CmdRecFileOK); except on e:Exception do Log(e.Message); end; end; end;
Delphi-Quellcode:
hehe
procedure TForm1.TCPServerExecute(AContext: TIdContext);
var FSTream: TFileStream; df: String; tmpClientData : TClientData; begin if not assigned(AContext.Data) then begin AContext.Connection.Disconnect; exit; end; // read clientdata try tmpClientData := TClientData(AContext.Data); except AContext.Connection.Disconnect; exit; end; // check state if (tmpClientData.Status = cCSGoing2Disconnect) or (tmpClientData.Status = cCSDisconnected) then begin AContext.Connection.Disconnect; exit; end; // get command try tmpClientData.LastCmd := AContext.Connection.Socket.ReadLn(#$A,5000,1024); except tmpClientData.LastCmd := ''; end; // check the old command case tmpClientData.LastIntCmd of // GUY WANTS TO SEND FILE 1: begin savefilepath := DestinationEdit.Text + AContext.Connection.IOHandler.ReadLn; Log(AContext.Binding.PeerIP+' wants to send file: "'+ExtractName(savefilepath)+'"'); ButtonCaption('receive'); EButton4.Enabled := True; end; // UPLOAD FILE 2: begin Log('upload file...'); TCPSendCmd(4); try // upload FStream := TFileStream.Create(uploadfilepath, fmOpenRead or fmShareDenyWrite); TCPClient.IOHandler.Write(FStream,0,true); // disconnect AContext.Connection.Disconnect; if TCPClient.Connected then TCPClient.Disconnect; tmpClientData.Status := cCSDisconnected; finally FStream.Free; end; Log('successfully uploaded'); ButtonCaption('upload'); EButton4.Enabled := False; EButton2.Enabled := True; EButton5.Enabled := True; end; // GUY REFUSED FILE 3: begin Log('guy refused to download file'); // disconnect AContext.Connection.Disconnect; if TCPClient.Connected then TCPClient.Disconnect; tmpClientData.Status := cCSDisconnected; ButtonCaption('upload'); EButton4.Enabled := False; EButton2.Enabled := True; EButton5.Enabled := True; end; // DOWNLOAD FILE 4: begin try if FileExists(savefilepath) then begin Log('file was already existing'); df := savefilepath; DeleteFile(df); Log('old file deleted!'); end else if DirectoryExists(ExtractFilePath(savefilepath)) = false then begin CreateDir(ExtractFilePath(savefilepath)); Log('directory "'+ExtractFilePath(savefilepath)+'" created'); end; Log('download...'); try // download FStream := TFileStream.Create(savefilepath, fmCreate); AContext.connection.IOHandler.ReadStream(fstream); // disconnect AContext.Connection.Disconnect; if TCPClient.Connected then TCPClient.Disconnect; tmpClientData.Status := cCSDisconnected; finally FStream.Free; end; Log('file successfully downloaded!'); ButtonCaption('upload'); EButton4.Enabled := False; EButton2.Enabled := True; EButton5.Enabled := True; except on e:Exception do Log(e.Message); end; end; // RECEIVE CHAT MESSAGE 5: begin Log(AContext.Binding.PeerIP+': '+AContext.Connection.IOHandler.ReadLn); AContext.Connection.Disconnect; end; end; end;
Delphi-Quellcode:
procedure TForm1.TCPSendCmd(Cmd: Byte);
begin try TCPClient.IOHandler.WriteLn(IntToStr(Cmd)); except on e:Exception do Log(e.Message); end; end; |
Re: indy10 / TCPServer /TCPClient ->Datei versenden
Hi,
so jetzt frage ich doch nochmal... Was ich will: Ich will ein TJpegImage oder TBitmap in einen Stream speichern und dann den Stream über TCPClient an den TCPServer senden. (Höhrt sich einfach an, treibt mich aber noch in den Wahnsinn) Das schlimme dabei ist, ich benutze Indy 10 und da gibt es keinen 'WriteStream'! :roll: Wie ich es bisher umgangen hab: Ich hab das JPG in eine Datei gespeichert und die Datei dann versendet, empfangen, geladen, gelöscht und das funktioniert auch perfekt nur ist es halt regelrecht lahm aufgrund der vielen Festplattenzugriffe. Bisher hab ich folgendes:
Delphi-Quellcode:
Bei der Filesize weiß ich, das sie den richtigen Wert enthält.
// Client sendet den Stream
memStream := TMemoryStream.Create; jpgTmp.SaveToStream(memStream); memStream.Position := 0; FClient.IOHandler.Write(memStream); // Server epfängt den Stream memStream := TMemoryStream.Create; AContext.Connection.IOHandler.ReadStream(memStream,FileSize); memStream.Position := 0; jpgTmp.LoadFromStream(memStream); Wenn ich aber das Debug hängt der Client in 'Write' und der server in 'ReadStream' und weiter gehts nicht mehr. :gruebel: Oder habe ich eventuell jetzt schon einen Fehler gemacht? :pale: Zitat:
Ich hoffe irgendwer hat eine Lösung parat bzw kann mir helfen, dass ich den Stream versendet und empfangen bekomm. Danke schonmal! |
Re: indy10 / TCPServer /TCPClient ->Datei versenden
schau dir bitte den Beitrag von ManuMF #21 an, das wird bestimmt helfen
|
Re: indy10 / TCPServer /TCPClient ->Datei versenden
Zitat:
Die Unit 'IdStreamVCL' enthält bei mir keinen Typ 'TidStreamVCL' sondern nur 'TIdStreamHelperVCL'. (Welcher nichtmal einen Parameter im Create hat) |
Re: indy10 / TCPServer /TCPClient ->Datei versenden
schau dir den Beitrag #10 an
|
Re: indy10 / TCPServer /TCPClient ->Datei versenden
Mit dem Post wolltest du wahrscheinlich auf diesen Thread hinweisen.
Das ist aber genau der murks den ich momentan mache. (wie bereits erwähnt) Da werden keine Daten direkt versendet per Stream, da wird erst in eine Datei gespeichert, die Datei wird versendet und beim Empfänger gespeichert, Beim empfänger wird die Datei geladen und dann erst hat man den Stream/Inhalt. Das ganze hin und hergespeichere kann man sich doch bestimmt ersparen indem man direkt einen Stream versendet, nur wie? :cry: Naja ich hau jetzt Indy 10 raus und Indy 9 rein. Dann hab ich auch mein 'WriteStream' und die Welt ist heile... :thumb: (hoffentlich^^) Danke trotzdem! |
Re: indy10 / TCPServer /TCPClient ->Datei versenden
für Indy 9 wirst du im Delphitreff forum viel finden
|
Re: indy10 / TCPServer /TCPClient ->Datei versenden
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 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