Entwickler-Ecke

Internet / Netzwerk - Datei wird nicht richtig emfangen


-->Masterkill<-- - Sa 19.08.06 14:17
Titel: Datei wird nicht richtig emfangen
Hallo ich habe einen art "Screenshotmaker" programmiert und will die Datei nun über Stream verschicken, doch kann ich irgendwie nur Dateien bis zu (genau) 4096 Byte verschicken.

Hier der relevante Code:

Server:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Screencapture(bmp); // Funktion, die den Bildschirminhalt in den String bmp speichert
bmp.SaveToFile('C:\temp\screenshot.bmp'); // Datei wird zwischengespeichert
bmp.Free; // Zugriff freigeben

Socket.SendStream(TFileStream.Create('C:\temp\screenshot.bmp', fmOpenRead or fmShareDenyWrite)); // Datei als Stream an den Client senden

DeleteFile('C:\temp\screenshot.bmp'); // Zwischengespeicherte Datei löschen


Client:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
FStream: TFileStream;
SizeOfFile: Integer;
pBuffer: Pointer;

begin

FStream := TFileStream.Create('C:\datei2.bmp', fmOpenWrite); // Zieldat. zum Schr. öffnen

  SizeOfFile := Socket.ReceiveLength; //Länge emfangen (Liegt dort der Fehler?)
  GetMem(pBuffer, SizeOfFile); // .... könnt ihr euch nun selber denken
  try
    Socket.ReceiveBuf(pBuffer^, SizeOfFile);
    FStream.Write(pBuffer^, SizeOfFile);
  finally
    FreeMem(pBuffer);
    FStream.Free;
       
  end;
  end;


Ich hoffe ihr könnt mir sagen wo ich den Fehler gemacht hab
MFG Masterkill

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


Born-to-Frag - Sa 19.08.06 15:04

Weil du immer nur max. 8KB empfängst wenn die Prozedur OnClientRead aufgeruen wird.. also brauchst du ein Protokoll [http://www.delphi-library.de/viewtopic.php?t=54269] ;) Erst Dateigröße mitteilen, dann Datei empfangen und sobald alles rüber ist -> Stream freigeben

Aber user profile iconNarses wird dir das bestimmt gleich noch ausführlich erklären :mrgreen:


-->Masterkill<-- - Sa 19.08.06 17:43

OK danke werd ihn mal fragen.
MFG Masterkill


Narses - So 20.08.06 00:40

Moin und :welcome: im Forum!

Vorab:
user profile icon-->Masterkill<-- hat folgendes geschrieben:
Hier der relevante Code:

Bitte verwende die Delphi-Tags für den Code im Editor, dann wird der Code durch Syntaxhighliting viel besser lesbar. Du kannst das in einem Beitrag auch nachträglich noch ändern, einfach auf den Edit-Button oben rechts im Beitrag klicken: user defined image

Jetzt zu deinem Problem:

Delphi-Quelltext
1:
Socket.SendStream(TFileStream.Create('C:\temp\screenshot.bmp', fmOpenRead or fmShareDenyWrite)); // Datei als Stream an den Client senden                    

Damit ist unklar, wie groß der Stream ist, also wieviele Bytes jetzt folgen.

Dieses Ereignis tritt ein, wenn Daten eintreffen:

Delphi-Quelltext
1:
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);                    

Das heißt aber nicht, dass alle Daten eingetroffen sind! :shock:

Wie user profile iconBorn-to-Frag schon ganz richtig erkannt hat, erhälst du mit dieser Funktion lediglich die Anzahl der Bytes, die aktuell eingetroffen sind, und da der WSA-Buffer nur 8kb groß ist, sind das eben nur max. 8kb!

Delphi-Quelltext
1:
SizeOfFile := Socket.ReceiveLength; //Länge emfangen (Liegt dort der Fehler?)                    


Fazit: Du mußt die Größe des Streams übertragen und dann soviele Bytes lesen, was aber über mehrere OnClientRead-Ereignisse der Fall sein wird.

Das Problem ist am besten mit einem Protokoll zu lösen, hier ist ein Beispiel [http://www.delphi-library.de/topic_ProtokollChatTutorial+TServerSocketTClientSocket+v300_54269.html], wie man sowas machen könnte.

cu
Narses


-->Masterkill<-- - So 20.08.06 11:03

Ok danke erstmal!

Das heißt also jetzt ich soll mir das Tutorial durchlesen und dann ein eigenes Protokoll entwerfen.

/* Kurz gefragt gibt es keine Möglichkeit das mit Records zu machen? */

mfg Masterkill


//Edit

Habe grade das Tutorial gelesen, warum man keine Records benutzen soll^^
Also wenn es sont keine Lösung außer des Protokolles gibt werd ich das Tutorial durcharbeiten...
Bin aber für andere Lösungsvorschläge offen.
Mfg Masterkill


Narses - So 20.08.06 11:12

Moin!

user profile icon-->Masterkill<-- hat folgendes geschrieben:
Das heißt also jetzt ich soll mir das Tutorial durchlesen und dann ein eigenes Protokoll entwerfen.

Das wäre meine Empfehlung, ja. ;)

user profile icon-->Masterkill<-- hat folgendes geschrieben:
Kurz gefragt gibt es keine Möglichkeit das mit Records zu machen?

Doch, die Möglichkeit gibt es. Meine Meinung dazu kann du hier [http://www.delphi-library.de/topic_Probleme+beim+SendenEmpfangen+von+records++dyn+Objekten_60793.html]lesen. :mrgreen:

cu
Narses


-->Masterkill<-- - So 20.08.06 11:14

Oh lol ok mein Edit kam zu spät