Entwickler-Ecke

Internet / Netzwerk - Dateien über sockets übertragen --> nie mehr als 8 KB


Marco D. - Sa 13.08.05 13:33
Titel: Dateien über sockets übertragen --> nie mehr als 8 KB
Ich will in einem Chat -Programm Dateien über die Sockets übertragen.

Dazu gibt es ein Server- und ein Client-Programm. Der Server wählt über einen Opendialog ne Datei aus, und mit nem Klick auf 'Absenden' bekommt der User des Client-Programms die

Meldung, dass die Datei 'xxx.yyy' zum Abruf bereit steht. Dieser User wählt dann über 'selectdirectory' aus der Unit 'FileCtrl' ein Verzeichnis aus, und drückt auf 'Abholen'.
Wenn ich dann das Zielverzeichnis kontrolliere, ist die Datei zwar da. Bei Dateien unter 8 KB funktionierts, doch Dateien die diese Dateigröße überschreiten, sind im Zielverzeichnis halt

nur 8 Kilobyte groß. Es ist also so, dass die Methode, die ich verwende, eigentlich funktioniert, doch bei Dateien über 8 KB ist dann halt schluss, denn diese werden nur zum Teil übertragen

und sind somit nutzlos.
Das Ziel meines Programms, soll sein, Dateien im Netzwerk bequem und einfach zu übertragen.

Hier mein Quellcode:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
with opendialog1 do
begin
if execute then
begin
edit2.Text:=extractfilename(filename); //Der Dateiname wird in edit2 ausgegeben
end;
end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
if not (edit2.text=''then //überprüfen, ob überhaupt ne Datei ausgewählt ist
begin
FStream := TFileStream.Create(opendialog1.filename, fmOpenRead);  //schreiben der Datei in einen TFileStream
for i := 0 to serversocket2.socket.activeconnections-1 do 
//Alle mit dem Serversocket verbundenen Clientsockets //durchgehen
begin
serversocket1.socket.connections[i].sendtext('Der Administrator hat folgende Datei zum Abruf bereit gestellt: '+extractfilename(opendialog1.filename));
//serversocket1 ist für die Übermittlung von chatnachrichten zuständig
//Er gibt hier die Ankündigung der Datei aus
sleep(100);
//Der Dateiname wird an das Client-Programm übermittelt
// Um diese Angabe von herkömmlichen Nachrichten zu unterscheiden
// beginnt diese mit 'file#'; z.B. 'file#test.txt'
serversocket1.socket.connections[i].SendText('file#'+extractfilename(opendialog1.filename));
sleep(300);
//Der Serversocket2, zuständig für Übertragen der Filestreams, sendet die Datei an alle verbundenen Clientsockets
serversocket2.socket.connections[i].sendstream(fstream);
sleep(500);
end;
end;


Jetzt der Code ausm Client-Programm


Delphi-Quelltext
1:
2:
3:
4:
// Der User wählt das Verzeichnis aus, wo die empfangene Datei gespeichert werden soll
if selectdirectory('Wo soll die gesendete Datei gespeichert werden?','',verzeichnis) then
begin
end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
//prüfen ob dies die Angabe für den Dateinamen ist (s ist der socket.receivetext)
if (s[1]+s[2]+s[3]+s[4]+s[5]='file#'then
begin
dateiname_empfangen:='';
// den Dateinamen Zeichen für Zeichen auslesen
for i := 6 to length(s) do
begin
dateiname_empfangen:=dateiname_empfangen+s[i];
end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
// diesen Quellcode versteht ich nich wirklich
// Ich hab ihn aus:
// Navigation:  Delphi-Forum.de Foren-Übersicht  » FAQ: Internet / Netzwerk  » ...eine Datei über die Sockets verschicken?  von O'rallY kopiert und angepasst
var 
  FStream: TFileStream;
  SizeOfFile: Integer; 
  pBuffer: Pointer;
begin

  FStream := TFileStream.Create(verzeichnis+'\'+dateiname_empfangen, fmcreate or fmOpenWrite);
  SizeOfFile := clientsocket2.Socket.ReceiveLength;
//der Clientsocket2 ist für das Empfangen des Filestreams verantwortlich, den der Serversocket2 geschickt hat
  GetMem(pBuffer, SizeOfFile); 
  try 
    clientsocket2.Socket.ReceiveBuf(pBuffer^, SizeOfFile); 
    FStream.Write(pBuffer^, SizeOfFile); 
  finally 
    FreeMem(pBuffer);
    FStream.Free;
  end;


Wie gesagt, das Problem ist dass nur maximal 8 Kilobyte übertragen werden. Ich würde mich sehr freuen, wenn ihr mir sagen könntet, wo das Problem liegt, weil das Program fürs

Schulznetzwerk gedacht ist (der Lehrer hat übrigens KEIN Problem damit) und das neue Schuljahr bei uns angefangen hat und es daher ziemlich eilig ist.

Danke

MfG Koller


Narses - Sa 13.08.05 14:27

Moin!

Mir fallen da zwei Sachen direkt auf, ohne den Code wirklich näher "begutachtet" zu haben:
1. Du sendest den Namen der Datei und direkt danach den Stream... :gruebel: woher weißt du denn, dass der Client auch schon empfangsbereit ist?
2. Der Client-Code zum Empfangen kann so nicht funktionieren; du solltest vielleicht keinen Code "abschreiben", den du nicht verstehst.

Mein Rat an dieser Stelle - wie immer :mahn: - du brauchst ein Protokoll! Mit einem solchen kannst du dann die Datei stückchenweise durchs Kabel schieben, so wird das nix.

Alternative: Mach einen weiteren Client/Server auf, der nur zum Senden der Datei-Streams da ist (halt so wie bei FTP). Nebenbei gesagt: warum immer das Rad neu erfinden, warum nicht gleich auf FTP aufsetzen... :wink:

cu
Narses


Marco D. - So 14.08.05 15:17
Titel: Sockets
@ Narses:

Ich muss sagen, wenn ich nicht weiß wies geht, dann kann ich doch nur abschreiben oder was sonst?

Zum Thread-Thema, okay ich werds mit FTP probieren. Kann es sein, dass wir da auf die guten alten Indys zurückkommen, wenns um FTP geht oder welche Komponenten braucht man dafür?


Narses - So 14.08.05 23:14

Moin!

user profile iconKoller hat folgendes geschrieben:
Ich muss sagen, wenn ich nicht weiß wies geht, dann kann ich doch nur abschreiben oder was sonst?

Alternative: Code verstehen und dann selbst reproduzieren; hat den Vorteil, dass man dann auch (selbst!) Fehler suchen kann... :wink:

user profile iconKoller hat folgendes geschrieben:
Zum Thread-Thema, okay ich werds mit FTP probieren. Kann es sein, dass wir da auf die guten alten Indys zurückkommen, wenns um FTP geht oder welche Komponenten braucht man dafür?

Denke, die Indies sind wohl die einfachste Lösung für diesen Ansatz (den FTP-Teil, sonst kannste ja bei TServerSocket und TClientSocket bleiben).

cu
Narses