![]() |
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 |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Leute,
anbei ein kleines Bsp. Schaut's auch an und gebt bitte ne Rückmeldung, wenn man was verbessern kann. Mir schon klar das die Benutzung von TMemoryStream bei größeren Datei Probleme versucht :mrgreen: Aber das ganze war ja auch mal schnell nebenbei gemacht :wink: Gruß Data P.S.: Verwendet wurde D5 mit Indy 9 |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hallo Leute...
Ich habe mir den Code von DataCool ein Posting höher herunter geladen. Leider bekomme ich beim start der Client.dpr folgende Meldungen... ![]() ![]() DataCool sagte er habe es unter D5 mit indy 9 geproggt. Kann es sein, dass mir (D6) irgendetwas fehlt? Gruss, Holi |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi Holidudu,
kann es sein das Du nicht die aktuellste Version der Indys benutzt ? Aktuell ist gerade 9.0.14 !!Die hab ich auch verwendet ! Download unter : ![]() Wenn Du Delphi 6 verwendest, ist zwar Indy mit installiert aber in einer älteren Version. Gruß Data |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Schön, dass du mir so schnell geantwortet hast. :wink:
Kannst du mir vieleicht noch erklären wie man die Indys updated? Ich bin nämlich noch nicht allzu weit mit Delphi. Bin schon froh, dass ich dieses Forum gefunden habe... :mrgreen: Edit: Naja... um ehrlich zu sein bin ich ein schlechter english-interpreter um die eventuellen Install-Anweisungen richtig zu verstehen. :zwinker: |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi,
wie war das den gleich noch mal :gruebel: Angaben ohne Gewähr :mrgreen: 1. Das Indy Package deinstallieren und entfernen. 2. In irgenteinem Unterverzeichnis von Delphi 6 müssen alle Indy-Dateien(Id*.pas und Id*.dcu) gelöscht werden. 3. Danach das neue Indy-Package installieren Gruß Data |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
hehe... lieb von dir! :drunken:
Ok... das krieg ich auch anderweitig (seltsames Wort) raus. :zwinker: Aber nun mal was anderes: Ich habe mir deinen Code mal innig angeschaut. Und nachdem ich selber nun schon über eine Woche mir den Hals nach einer funktionierenden Variante verrengt habe indem ich es selber versucht habe, muss ich angesichts deiner Leistung passen. Es gibt nach meinen google-erkenntnissen keine bessere Beschreibung für das Problem Dateien zu verschicken. Jedenfalls nicht im deutschsprachigen Raum. Mein höchster Respekt davor ist dir sicher! :wink: Aber mal ne Frage: Die *.exe Dateien funktionieren ja auch bei mir... auch ohne indy-update. Aber warum bekommt der Server keine SaveDialog-Abfrage? Ich meine... sowas müsste doch vor dem Senden der Parts geschehen, oder? Ich kann Dateien versenden mit Statusanzeige auf beiden Seiten. Genial! Nur wie speichere ich das Empfangene... und wo? :freak: |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi,
also wenn Dir meine Arbeit so gefällt, dann zieh Dir ![]() rein, das ist ein Messenger den ich auf Indy Basis geschrieben habe. Meine Nummer da 1011 Aber zu Deiner Fragen : 1. Warum wird kein Save-Dialog verwendet : Nun der Sinn einer Server-Anwenung ist es ja Multi-Threaded zu Laufen, d.h. das der Server mehere Anfragen auf einmal bearbeiten kann. Du kannst einen Save-Dialog verwenden, dieser müßte nur syncronisiert aufgerufen werden. Aber die ist absolut gegen den Sinn eines Servers, weil der Server dann auf eine User-Eingabe warten muss und ein Server sollte selbstständig arbeiten. 2. Wie jetzt mit den gesendeten Dateien umgehen ? Z.B. alle ankommenden Dateien in einem bestimmten Verzeichnis z.B. "Incomeing Files" ablegen. Damit die Dateinamen eindeutig sind kannst Du temporäre generierte Namen verwenden. Entweder über die Windows-Funktion oder durch z.B. "file_"+inttostr(AThread.ThreadID) oder Du schickst den Namen der Datei mit bevor Du den Stream sendest. 3. Ich habe noch ein weiters Bsp. zu dem Thema hier gepostet, weil das erste hier ein Quick-Hack war und ich mit dem Ding nicht wirklich zufrieden war : ![]() Gruß Data |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Zitat:
Danke erstmal für die tolle Hilfe hier! Ich melde mich dann morgen in aller Frische... :love: |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
@ DataCool
Zitat:
Aber darum geht es mir eigentlich garnicht in erster Linie... :roll: An welcher Stelle in deinem code könnte ich z.B. am besten sowas wie einen SaveDialog einbauen? Ich möchte, dass man optional wählen kann ob man das File gezielt auf Platte oder in einem Incoming speichern will. Ich bin deswegen der Meinung, (dass das Sinn macht) weil man das Programm dadurch auch fürs LAN tauglich machen würde. So nach dem Motto: "He Otto... schieb doch mal eben das neueste Moorhuhn rüber!" :arrow: :dancer2: Und da wäre es praktisch wenn der Server-User das File gezielt ablegen könnte. Nur so als Option, weisst du? :wink: |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Hi Holidudu,
der Sinn und Unsinn des SaveDialogs ist mir schon klar :wink: Wenn Du gerne dem Benutzer die Möglichkeit zum gezielten Speichern geben möchtest, dann mach es doch ähnlich wie Kazaa und eMule ! Mach Dir ein Verzeichnis Incoming Files ! Dort speichere zuerst die angekommenden Dateien ! In einer Listbox oder einen Listview zeigst Du dem User als empfangene Dateien an, dort kann er Sie dann über einen SaveDialog woanders hin speichern. Wenn Du damit nur was wie einen FileTransfer wie bei ICQ hinbekommen willst, kannst Du auch mit einen Save-Dialog aus der Server Code raus arbeiten, aber wie vorher schon gesagt, dieser muss dann syncronisiert aufgerufen werden. Gruß Data |
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
Ja danke... die Idee ist gut. Einfach eine Listbox mit allen geladenen Files und darauf eine Umlagerungsmöglichkeit...*patsch*. Hätte eigentlich selbst drauf kommen müssen :roll:
|
Re: Probleme beim Versenden von Dateien mit Indy TCPClient
@DataCool
Ich bin jetzt mal dazu gekommen daran zu arbeiten das File zu speichern. Leider ist mir absolut schleierhaft, warum das nach dem Splitten wieder zusammen gebappte File im Ordner C:\ landet... Kannst du mir das vieleicht mal erläutern, damit ich überhaupt an sowas wie einen Incoming arbeiten kann? :cyclops: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:28 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-2025 by Thomas Breitkreuz