![]() |
Probleme beim Versenden von Dateien mit Indy TCPClient
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
ich habe ein kleines Client-Programm geschrieben, das einem Server-Programm Dateien schicken kann. (Siehe Anhang). Leider tritt dabei ein Problem auf. Bei Dateien die größer sind als ca. 220kb bekomme ich vom Debugger folgende Fehlermeldung: "Im Projekt pSentStream.exe ist eine Exceptionder Klasse EIdSocketError aufgetreten. Meldung: 'Socket-Fehler #10053 Die Software hat den Abbruch der Verbindung verursacht.'.Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen" Weiß jemand wodran das liegt? Ich vermute ein Problem mit dem Buffer. Aber gefunden habe ich den Fehler nicht. :? Ich hoffe ihr könnt mir helfen Gruß Christian |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hat denn keiner eine Idee? :wall:
Ich bin auch offen für Vorschläge :lol:. Also, wenn jemand weiß wie ich das komplett anders viel besser machen kann, dann nur her mit euren Ideen. :hi: Für jemanden der Angst vor Viren hat, hier noch eben der Quelltext beider Programme: Client:
Delphi-Quellcode:
Server:
unit mSentStream;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdAntiFreezeBase, IdAntiFreeze; type TSentStream = class(TForm) IdTCPClient1: TIdTCPClient; btDateisenden: TButton; OpenDialog1: TOpenDialog; edIP: TEdit; Label1: TLabel; lbPort: TLabel; IdAntiFreeze1: TIdAntiFreeze; procedure btDateisendenClick(Sender: TObject); private { Private-Deklarationen } procedure Datei_senden; public { Public-Deklarationen } end; var SentStream: TSentStream; implementation {$R *.dfm} //Methode Datei_senden__________________________________________________________ procedure TSentStream.Datei_senden; var fs: TFileStream; begin if not OpenDialog1.Execute then exit; with IdTCPClient1 do begin fs:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead or fmShareDenyWrite); Connect; if Connected = true then WriteLn(OpenDialog1.filename) //Der Filename wird verschickt else Showmessage ('nicht verbunden'); try OpenWriteBuffer; try WriteStream(fs, true, true, 0); CloseWriteBuffer; except CancelWriteBuffer; raise; end; finally Disconnect; fs.Free; end; end; end; //Ende Methode Datei_senden_____________________________________________________ //Daten-Transfer starten________________________________________________________ procedure TSentStream.btDateisendenClick(Sender: TObject); begin //Der Hostname wird auf das edit-Feld edIP gesetzt IdTCPClient1.Host := edIp.text; Datei_senden; end; //Ende Daten-Transfer starten___________________________________________________ end.
Delphi-Quellcode:
Gruß
unit mGetStream;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls; type TGetStream = class(TForm) IdTCPServer1: TIdTCPServer; SaveDialog1: TSaveDialog; btaktivieren: TButton; edPfad: TEdit; edFilter: TEdit; lbFilter: TLabel; lbPfad: TLabel; edFilename: TEdit; lbFilename: TLabel; procedure IdTCPServer1Execute(AThread: TIdPeerThread); procedure btaktivierenClick(Sender: TObject); private { Private-Deklarationen } function trueFilename (Filename :TFilename) :tFilename; function filter (Filename :TFilename) :string; public { Public-Deklarationen } end; var GetStream: TGetStream; implementation {$R *.dfm} //idTCPServer1 OnExecute:_______________________________________________________ procedure TGetStream.IdTCPServer1Execute(AThread: TIdPeerThread); var fs: TFileStream; SizeOfIncomingStream: integer; Filename :TFilename; begin //###################################### Filename := Athread.Connection.ReadLn ; //trueFilename ist eine Funktion, die aus dem Pfad den Dateinamen filtert SaveDialog1.filename := truefilename (Filename); //SaveFilter ist eine Methode, um die Endung der Datei zu bestimmen SaveDialog1.Filter := filter (Filename); edPfad.text := filename; edFilename.text := SaveDialog1.Filename; edFilter.text := SaveDialog1.Filter; //###################################### //Der SaveDialog wird ausgeführt und die Datei wird gespeichert. 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; //Ende IdTCPServer1 OnExecute___________________________________________________ //Funktionen:___________________________________________________________________ //trueFilename ist eine Funktion, die aus dem Pfad den Dateinamen filtert function TGetStream.trueFilename(Filename :TFilename):tFilename; var backslash :boolean; i :integer; begin i := 0; backslash := false; //Der Dateiname ohne Pfaangabe wird gefilter while backslash= false do begin if copy (Filename,length (Filename)-i,1) = '\' then begin trueFilename := copy (Filename,length (Filename)-i+1,i); backslash := true end else i := i+1; end; end; //Filter ist eine Funktion die im Filename nach der Endung sucht function TGetStream.Filter (Filename :TFilename) :string; var dot :boolean; i :integer; begin i:= 0; dot := false; while dot= false do begin if copy (Filename,length (Filename)-i,1) = '.' then begin filter := '*.'+copy (Filename,length (Filename)-i+1,i)+ '|'+copy (Filename,length (Filename)-i+1,i); dot := true end else i := i+1; end; end; //Ende der Funktionen___________________________________________________________ //Serverstart:__________________________________________________________________ procedure TGetStream.btaktivierenClick(Sender: TObject); begin if btaktivieren.Caption = 'Server aktivieren' then begin idtcpServer1.active := true; showmessage ('Dienst gestartet'); btaktivieren.Caption := 'Server deaktivieren' end else begin idtcpServer1.active := false; btaktivieren.Caption := 'Server aktivieren' end; end; //Ende Serverstart______________________________________________________________ end. Christian |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi Chris,
ich sehe in Deiner Vorgehensweise ein paar Probleme !!! Was soll das Programm den später genau können ? Warum schickst Du den Kompletten Datei-Pfad mit ? Der Client kann im Prinzip so bleiben, nur würde ich mir überlegen, ob Du wirklich den kompletten Pfad mitschicken willst/musst. Zum Server : Du verwendest die WriteStream-Funktion so, dass die Stream Grösse mitgeschickt wird. Beim Lesen des Streams versuchst Du selber die Grösse des Streams auszulesen, das must Du gar nicht, das macht die ReadStream-Funktion : Schreib es mal einfach so : ReadStream(ms); Das sollte der Grund für Deinen Fehler sein, habe den Fehler früher selbst so gehabt :mrgreen: Ein weiterer Gedankenfehler ist, dass der Server Multi-Threaded ist und Du in der Execute-Methode einen Modualen Dialog(Save) ausführst. Was passiert wenn zwei Clients Daten gleichzeitig senden ? Was passiert, wenn niemand den SaveDialog bestätigt ? Dann gibt es einen Timeout und dein Progg stürzt ab !!! Ich kann Dir gern ein paar mehr Tipps geben, habe mich im letzen Jahr sehe intensiv mit Indy beschäftigt, vor allen Dingen mit IdTcpClient u. IdTcpServer Gruß Data |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi Datacool
Also, wenn du noch ein paar Tipps für mich hättest wäre das prima. Ich hab nämlich schon viel im Forum gestöbert und bin dabei oft auf die gleichen Probleme gestoßen. (Z.B. "onwork" funktioniert nicht richtig ect.). Das Programm ist eigentlich mehr so eine Art Übung, um mal zu sehen was man mit den Indys so alles anstellen kann. Der meiste Quelltext ist aus der Code-Library und auf die Funktionen, die den Pfad zerpflücken war ich eigentlich ein bisschen stolz :oops: Was hast du mit den Indys denn schon alles gemacht? Ich scheitere z.B. auch kläglich an dem Programmieren einer Statusbar, um zu sehen wieviel von der Datei schon empfangen/versendet wurde. Hast du vielleicht ein kleines Beispiel-Programm für mich, wo du so einen Datentransfer schon sauber gelöst hast? Edit: Ich habe gerade mal probiert statt ReadStream(fs, SizeOfIncomingStream) einfach ReadStream(fs) zu benutzen. Leider funktioniert es nicht. Der Savedialog öffnet sich noch, aber wenn ich speichern will gibt es einen Fehler im Server. Was ich vergessen habe zu erwähnen: Der Fehler den ich oben beschrieben habe ensteht im Client, wenn ich den Client in Delphi bearbeite. Starte ich die *.exe ohne Delphi kommt folgender Fehler: "Socket-Fehler # 10053. Die Software hat den Abbruch der Verbindung verursacht" MfG Christian |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi Chris,
mein Hauptprojekt mit den Indys ist ein neuer Messanger, komplett in Delphi mit Indy ! Es ist ein Chat, telefonieren u. Cam2Cam möglich ! Das ganze ist auch schon online ![]() Aber ich benutze die Indy-Komponenten z.B. auch bei einer Anwendung im Gastronomie Bereich, wo es eine grosse Cafe-Kette gibt die in über 50 Standorten ein Programm von mir einsetzt, wo jeder eine lokele Firebird Datenbank hat. Diese 50 Datenbanken der einzelnen Standorte werden per Indy zur Zentrale übertragen und zu einer Main-DB Syncronisiert. DAmit in der Zentrale Reporting usw. durchgeführt werden können. Da arbeite ich auch mit einer Fortschrittsanzeige beim Übertragen der DB :mrgreen: Wo kann ich Dir denn jetzt konkret helfen ? Data |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Also,
ich habe oben meinen Thread nochmal editiert. Kannst du mir vielleicht den Code-Schnipsel zeigen, der die Datenbank verschickt und den Code der sie empfängt? Du wirst ja wahrscheinlich auch eine Datei versenden. Oder versendest du die Tabelle mit Strings? Wahrscheinlich nicht. (Das wäre so meine erste Idee, Daten zu übermitteln :lol: ) Ich will nur wissen wie man sowas sinnvoll angeht und was ich tun muss, um Dateien zu versenden die beliebig groß sind. Ausserdem bin ich durch das Konzept der IdTCPClient Kompo noch nicht so ganz durchgestiegen. Warum braucht man Buffer? Und warum auch noch 2? Gruß Christian |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi Chris,
ICQ hast Du nicht oder ? Lad Dir mal mein TelWell runter :mrgreen: Habe Nummer 1011 Wie kommst Du jetzt darauf das man zwei Buffer braucht ? Dein Code war schon soweit ganz ok, nur denn SaveDialog raus und das ReadInteger weglassen und dann nur readstream verwenden Schicke Dir morgen mal ein Code Bsp. Gruß Data |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
So,
ich bin jetzt online bei TelWell. Meine Nummer: 3831. Nur du bist noch nicht da :lol: Edit: Achja, was ich mit den 2Buffern meinte waren die Eigenschaften des idTCPClients im Objektinspektor. Da steht nämlich "RecvBufferSize" und "SendBufferSize". Wie meinst du das eigentlich mit der Readstream-Methode? ICQ hab ich auch: 251840671 Gruß Christian |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi,
mich quält ebenfalls das Problem der zu grossen Datenmenge und der nicht funktionierenden onwork Methode! Das den Anzeigen wurde ich nicht so recht schlau und der Teil mit der Fortschrittsanzeige fehlt komplett. Wäre sehr dankbar wenn die Lösung des Problems nochmals angezeigt wird:ALSO WAS ICH ÄNDERN MUSS AM BEISPIELCODE! DANKE @wardz :wiejetzt: |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi ATwardz,
ich habe für Chris ein kleines Demo geschrieben, wo Client und Server enthalten sind. Das Programm verschickt Dateien beliebiger Grösse, auf dem Server ist eine Fortschrittsanzeige schon fertig implementiert, beim Client bin ich dazu noch nicht gekommen. Werde den Quellcode gleich mal hochladen ! Gruß Data |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:48 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