| Autor |
Beitrag |
alleinherrscher
Hält's aus hier
Beiträge: 11
|
Verfasst: So 21.11.04 16:07
Hi@all
Ich benutzte den Standard - Indy - Code für das senden von Dateien von Client an Server, allerdings habe ich folgendes Problem: Auf dem einen Rechner ist Windows 2000, auf dem anderen 98. Auf einem dritten ist NT4.
Wenn ich dateien von 2000 nach 98 über mein Programm schicke, läuft alles wie vorgesehen, wenn ich allerdings von 98 auf 2000 oder NT Daten (also filestream) schicke, hängt sich der 98 - Client bei Dateien die größer als 0,5mb sind, auf...jemand ne ahnung warum? Auf beiden Rechner kommt exakt das gleiche Programm zur Anwendung!
Zwischen 2000 und NT ist das Daten schicken absolut kein Problem.
Hier die entsprechenden Routinen:
Der Client-Code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| Idtcpclient1.writeln('~fsm'+opendialog1.filename); <--Hier wird dem Server der Dateiname übergeben
memo1.lines.add('Trying to send File '+filename1 + ' to the remote computer');
with IdTCPClient1 do begin
fs := TFileStream.Create(filename1, fmOpenRead); try OpenWriteBuffer; try WriteStream(fs, true, true); <--- Hier bleibt Windows 98 hängen!!! CloseWriteBuffer; except CancelWriteBuffer; raise; end; finally fs.Free; Disconnect; end; memo1.lines.add('Transfer done!'); end;
end; |
Entsprechend der ServerCode (Client und Server sind in einem Programm untergebracht):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| text:=AThread.Connection.ReadLn();
typ:=copy(text,0,4);
if typ='~fsm' then begin dateiname:=copy(text,pos('~fsm',text)+4,length(text)-4); dateiname:=extractfilename(dateiname); filename1:=dateiname; endung:=copy(dateiname,pos('.',dateiname),length(dateiname)-pos('.',dateiname)+1); savedialog1.FileName:=filename1; savedialog1.Filter:=(endung+'|'+endung);
with AThread.Connection do try fs := TFileStream.Create('C:\filestream.tmp', fmCreate or fmShareExclusive); SizeOfIncomingStream := ReadInteger; ReadStream(fs, SizeOfIncomingStream); finally fs.Free; streamsend:=False; Disconnect; end;
AThread.Synchronize(speichern_unter);
exit; end; |
Wäre cool wenn jemand ne Idee hätte, hab allerseits die Indy Version 9.00.17.src und hoffe, ich muss keine andere installieren, weil das ja immer nen Aufstand ist...
 Liebe wochenendlichen Grüße,
Euer Alleinherrscher
|
|
r4id3n
      
Beiträge: 115
Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
|
Verfasst: So 21.11.04 21:17
Du solltest versuchen die Datei nicht in einem rutsch zu senden, sondern einzelne "Packete" daraus zu machen!
Lese dazu am besten z.b. jedes mal 10 - 100 kb der datei und sende diese einzeln ....
|
|
alleinherrscher 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mo 22.11.04 15:16
Titel: Packete sind genial!
| r4id3n hat folgendes geschrieben: | Du solltest versuchen die Datei nicht in einem rutsch zu senden, sondern einzelne "Packete" daraus zu machen!
Lese dazu am besten z.b. jedes mal 10 - 100 kb der datei und sende diese einzeln .... |
Hey, die Idee ist gut! Nur....wie muss ich meinen source umschreiben? habe mir zu diesem Thema gerade ein Beispiel ausm netz gezogen, allerdings verstehe ich da nur bahnhof
Jemand ne Idee, wie ich das möglichst einfach umsetzten kann mit dem Packet-schicken
lg, Alleinherrscher 
|
|
r4id3n
      
Beiträge: 115
Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
|
Verfasst: Mo 22.11.04 15:59
Der ReadBuffer-Methode kannst du angeben, wie viel du lesen möchtest....
Frag mich nicht nach der syntax, die steht in der Hilfe
Ebenso kannst du mit WriteBuffer eine bestimmte anzahl an Zeichen schreiben (length gibt dir die länge des strings)
Hoffe das hat geholfen!
|
|
alleinherrscher 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mo 22.11.04 19:34
Titel: Hä, wie jetzt?
Hmmm, also da ich mich so gar nicht mit den indy komponenten auskenne, hab ich mir jetzt diesen Code "gebastelt", der -natürlich- nicht funktioniert...
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| Idtcpclient1.writeln('~fsm'+opendialog1.filename); memo1.lines.add('Trying to send File '+filename1 + ' to the remote computer');
with IdTCPClient1 do begin fs := TFileStream.Create(filename1, fmOpenRead); iTmpSize := 0; tmpMS := TMemoryStream.Create; iFileSize := fs.Size; fs.Position := 0; while iTmpSize<iFileSize do begin tmpMs.clear; Application.ProcessMessages; iNextSize := iFileSize - iTmpSize; if iNextSize > packagesize then iNextSize := packagesize; iTmpSize := iTmpSize + tmpMs.CopyFrom(fs,iNextSize); try OpenWriteBuffer; WriteStream(tmpms, true, true,0); CloseWriteBuffer; except CancelWriteBuffer; end;
end;
fs.free; FreeAndNil(tmpMs); sendscreenshot:=False; memo1.lines.add('Transfer done!');
end;
end; |
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| iReceivedBytes := 0; fs := TFileStream.Create('C:\filestream.tmp', fmCreate or fmShareExclusive);
with AThread.Connection do
While (not AThread.Terminated) and (AThread.Connection.Connected) do begin tmpMS.clear;
SizeOfIncomingStream := ReadInteger; try ReadStream(tmpMS, SizeOfIncomingStream); if tmpMS.Size > 0 then begin fs.copyFrom(tmpMS,0);
iReceivedBytes := iReceivedBytes + tmpMS.Size; end; except showmessage('fehler!'); end; end; fs.Free; streamsend:=False; AThread.Connection.Disconnect; AThread.Synchronize(weitergehts);
exit; end;
AThread.connection.disconnect; AThread.Synchronize(weitere_bearbeitung); exit; |
Delphi gibt hier leider ne fehlermeldung zurück, die sehr wenig aussagefähig ist...wie das nun mal bei indy so ist...
Ne idee, was falsch ist, oder vielleicht sogar nen bessere lösung?
Sorry, dass ich gerade meine Programme von euch "Debuggen" lasse, aber wie gesagt, ich hab keine peilung von indy...delphi is eigentlich kein problem, aber zu indy habe ich noch nicht mal irgendeine anständige hilfedatei...
Liebe Grüße, Alleinherrscher 
|
|
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Mo 22.11.04 20:47
Hallo alleinherscher (ich hoffe dein Name ist nicht ernst gemeint  ),
ich weiss zwar nicht, welche Aufgabe dein Programm außer dem Kopiervorgang noch zur Verfügung stellt, aber ich würde grunsätzlich alle Dinge, die du zwischen zwei Programm kennzeichnen, z.B. durch einen einfach "Kopf" (Header): Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| const diSFileCopyStart = 1; diSFileCopyEnd = 2; diSFileCopyPart = 3; diEFileCopyAbort = 4;
diEFileCopyGetPart = 13; diEFileCopyAbort = 14;
diChat = 20; TDataHeader = record Id: Byte; Pos: Cardinal; Data: Pointer; | Wenn du nun eine Datei verschicken möchtest, dann solltest du, wie schon vorher vorgeschlage, die Datei in einzelne Stücke "zerlegen" und dann Stück für Stück übertragen. Das hat zum einen den Vorteil, dass du verlorengegangene Teilstücke einfach erneut schicken kannst und die Übertragen eventuell auch schneller geht, zumindest ist sie sicherer.
Wie du nun den Übertragungsvorgang vornimmst, das bleibt alleine dir überlassen. Ich möchte dir nur ein paar Tipps geben, die Übertragen vor Störungen schützen. Pseudoquelltext für die Übertragung: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| procedure Senden(Id1: Byte; Pos: Cardinal; var Data);
Senden(diSFileCopyStart); Senden(diEFileCopyGetPart, 0); Datei zum speichern öffnen (TFileStream) Senden(diEFileCopyAbort);
Datei öffnen (TFileStream); Erster Block einlessen (Größe: 1024 * x) Senden(diSFileCopyPart, Größe des Blockes, Block); Block speichern (TfileStream) Senden(diEFileCopyGetPart, Stream.Pos); Zur Position P wechseln Block einlessen Senden(diSFileCopyPart, Größe des Blockes, Block);
| So, jetzt bleibt es dir überlassen, diesen Pseudoquelltext in Quelltext um zusetzen. Indy bietet die Methode WriteBuffer und ReadBuffer (oder ähnliche), mit denen du die Aufgaben erfüllen kannst.
Viel Glück und wenn du Probleme hast, dann frag wieder!
Grüße,
Hape!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
|