Delphi-PRAXiS
Seite 2 von 5     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Dateiaustausch zwischen clientsocket und serversocket..^^ (https://www.delphipraxis.net/100996-dateiaustausch-zwischen-clientsocket-und-serversocket-%5E%5E.html)

Muetze1 6. Okt 2007 21:28

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
Joa, zum Beispiel. Das kannst du ja auch leicht abändern um statt einem FileStream ein TMemoryStream zu nutzen, wenn du keine Datei erstellen willst sondern das Bild nur anzeigen willst.

Fehlt nur noch das Problem: wann hast du das Bild komplett empfangen und kannst das Bild aus dem Stream lesen und diesen freigeben?

cRayZo 7. Okt 2007 20:42

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
also ich habs jetzt eingefügt und er startet auch ohne Probleme und connected auch ohne Probleme. Wenn ich beim Server per button einen screenshot machen will und ihn zu schicken, dann kommt dieser Fehler:
Zitat:

Zitat von Fehlermeldung
Zugriffsverletzung bei Adresse 004223BB in Modul Projekt1.exe. Lesen von Adresse 5557565B

ich hab den Fehler abgefangen. Er meckert dreimal im Code

Server:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Stream : TMemoryStream;
  bitmap:Tbitmap;
begin
 Stream := TMemoryStream.Create;
 MakeScreenShot(bitmap); //Fehlermeldung! Wundert mich, der Code war aus ner Codelibrary O:-)
 bitmap.SaveToStream(Stream); //Fehlermeldung!
 Stream.Position := 0;
 Serversocket1.Socket.Connections[0].SendStream(Stream);
 bitmap.Free; //Fehlermeldung!
end;
//edit: um herauszufinden wie lang der stream ist: würde doch so gehen oder?:
sizeof(stream) //


der Vollständigkeit halber hier nochmal der abgeänderte Clienttext:
Delphi-Quellcode:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Stream : TFileStream;
begin
Stream := TFileStream.Create('c:\teststream.bmp', fmCreate or fmShareDenyWrite);
clientsocket1.Socket.ReceiveBuf(stream,sizeof(stream));
image1.Picture.Bitmap.LoadFromStream(stream);
end;

Progman 7. Okt 2007 20:55

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Stream : TMemoryStream;
  bitmap:Tbitmap;
begin
Stream := TMemoryStream.Create;

bitmap:=TBitmap.create //!!

MakeScreenShot(bitmap); //Fehlermeldung! Wundert mich, der Code war aus ner Codelibrary O:-)
bitmap.SaveToStream(Stream); //Fehlermeldung!
Stream.Position := 0;
Serversocket1.Socket.Connections[0].SendStream(Stream);
bitmap.Free; //Fehlermeldung!
end;
das Create vergessen :)

cRayZo 7. Okt 2007 21:10

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
Zitat:

Zitat von Progman
das Create vergessen :)

hupsa^^ aber das semikolon bitte auch nicht ;-)

jo okay...jetzt hab ich zwei fehlermeldungen.

der CLient kann den stream nicht in den Pfad speichern und schon wieder eine Zugriffverletzung.
Delphi-Quellcode:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Stream : TFileStream;
begin
 Stream := TFileStream.Create('c:\teststream.bmp', fmCreate or fmShareDenyWrite); //hier der Fehler!
 clientsocket1.Socket.ReceiveBuf(stream,sizeof(stream));
 image1.Picture.Bitmap.LoadFromStream(stream);
end;

Muetze1 7. Okt 2007 21:58

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
Zitat:

Zitat von cRayZo
//edit: um herauszufinden wie lang der stream ist: würde doch so gehen oder?:
sizeof(stream) //

Zitat:

Zitat von Muetze1
2. Du gibst die Instanz bei ReceiveBuf() an, aber der will einen Zwischenpuffer haben. Du kannst die Instanz niemals bei dieser Funktion direkt angeben.
3. Instanzen sind intern nur Zeiger auf das Objekt im Speicher - siehe mein Beitrag zuvor. Was für das Senden gilt, gilt hier genauso für das Empfangen, schliesslich sind es jedesmal Instanzen.

Zitat:

Zitat von Muetze1
TBitmap ist eine Klasse und diese sind intern nur Zeiger. Wenn du nun ein TBitmap versendest, dann sendest du nur die Adresse im Speicherbereich deiner Applikation, wo das Objekt liegt. Somit: Keine Daten und nichts. Der Empfänger kann damit nichts anfangen, da an der angegebenen Adresse in seinem Speicherbereich was ganz anderes liegt.

Und was machst du? Du gibst wieder eine Instanz an ReceiveBuf() - dabei hatten wir das nun schon 2x in diesem Thread. Und jedesmal hatte ich dir geschrieben, das dies nicht geht!

SizeOf() genauso wenig, weil damit kannst du sogar noch eher erkennen das es nicht geht: Lass dir mal das Ergebnis von SizeOf() ausgeben: es ist immer 4, also 4 Bytes. Somit kann dies nicht sein!

cRayZo 7. Okt 2007 22:24

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
ja okay hab ich vergessen zu ändern. Liegt aber auch vielleicht daran, dass ich nicht weiß, wie ich es besser machen soll.
Receivestream gibt es nicht beim Clientsocket, für receive gibt es nur den buf!
Ich weiß jetzt dass es falsch ist, aber wie es richtig gehen soll, weiß ich auch nicht..
ich arbeite noch nciht so lange mit Delphi also bitte erwartet nicht zuviel
Ich versuch ja alles zu verstehen, und verstehs ja auch, aber was bringt es mir, wenn ich den Fehler kenne, aber kA hab wie ich ihn lösen soll? (außer dass ich ihn nicht nochmal mache, aber auch dafür muss ich es richtig wissen)
wär also ganz nett, wenn du mir eine Hilfe geben würdest, oder (was es uns beiden leichter machen würde, und dir viele nerven erspart ( :-D ) wenn du mir den Fehler verbesserst und deine Verbesserung begründest. Daraus kann ich am meisten lernen (falls es dir darauf ankommt) ;)

schonmal thx für die antwort^^
lg cRayZo

//edit: was mir grad auffällt: wens dutzen stört, der sagts bitte^^//

Muetze1 8. Okt 2007 00:54

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
Es gibt kein ReceiveStream, weil der Socket nicht weiss, wie lang ist denn der Stream. Er weiss nicht wieviele Daten er in den Stream reinschreiben soll und wann halt Schluss ist. Er selber ist reiner Datenüberträger. Alles was du ihm gibst, schickt er so unverändert über den Socket raus. Wenn du SendStream() aufrufst, dann schreibt er einfach alle Daten aus dem Stream in den Socket bis der Stream zu Ende ist. Aber: als Empfänger weiss er nicht was für Daten da ankommen, woher und wie lang. (Als Sender interessiert ihn das auch herzlich wenig). Langer Rede, kurzer Sinn: es gibt kein ReceiveBuf(), weil die Socket Komponenten das gleiche Problem beim empfangen haben wie du: wann fängt der Stream an und wie lang ist er? Wann ist der Stream fertig? Der Socket könnte natürlich vor dem Stream die Grösse des selbigen übertragen, aber das macht er nicht, weil er damit sonst eine Art Protokoll definieren würde - und das macht er nicht. Er soll nur rein Daten übermitteln und sich darin keine Ordnung festlegen. Das ist nun deine Aufgabe.

Und zu deinem Problem mit dem ReceiveBuf: ReceiveBuf() will einen Buffer sehen, in den er die Daten reinschreiben kann. Danach kannst du den Buffer in deinen Stream schreiben. Ich habe dir die gesamte Zeit keinen Quelltext dazu gegeben sondern nur die Fehler aufgezeigt, da du selber eine passende Routine zum empfangen mit Puffer schon gepostet hast: hier. Damit hast du das eine Problem schonmal gelöst: Daten empfangen und in einen Puffer bekommen und danach weiter in den Stream.

Das einzige was noch fehlt: wann den Stream anlegen und wann hast du ihn komplett empfangen so dass du das Bild aus dem Stream laden kannst? Irgendwelche Ideen?

cRayZo 8. Okt 2007 16:09

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
der sender (hier der server) könnte, nachdem er alle Daten gesendet hat, eine msg schicken, dass er fertig gesendet hat.

und wenn du mich jetzt nicht vollständig durcheinandergebracht hast, sollte das dann so aussehen?
Delphi-Quellcode:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  iLen: Integer;
  Bfr: Pointer;
  Stream : TFileStream;
begin
  iLen := Socket.ReceiveLength;
  GetMem(Bfr, iLen);
  try
    Socket.ReceiveBuf(Bfr^, iLen);
    FStream := TFileStream.Create('c:\teststream.bmp', fmCreate or fmShareDenyWrite); //edit: der müsste außerhalb von onread erstellt werden oder verwechsel ich jetzt wieder was?
    FStream.Write(Bfr^, iLen);

    //hier die msg, dass Bild da ist isowas wie if receivetext=bla then
    image1.Picture.Bitmap.LoadFromStream(Fstream);
  finally
    FreeMem(Bfr);
  end;
end;

Muetze1 8. Okt 2007 16:30

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
Deine Kommentare sind richtig: Create des Streams ausserhalb von OnRead und das anzeigen, wenn er fertig is.

Aber zu deiner Idee mit der Message: Was ist - egal wie die Message nun im Endeffekt aussieht - wenn genau diese Bytefolge in dem übertragenen Bild enthalten ist? Dann bricht er zu früh ab und versucht ein unvollständiges Bild zu laden.

Wäre nicht die Übermittlung der Grösse der Bilddaten vor diesen sinnvoller?

Ein anderes Problem: ReceiveText weisst nicht ob die Daten im Socket Text oder andere Daten sind. Wenn du noch nicht fertig alles empfangen hast, dann würdest du mit ReceiveText sogar die Daten als string bekommen...

cRayZo 8. Okt 2007 16:51

Re: Dateiaustausch zwischen clientsocket und serversocket..^
 
also kann ich im server, wenn ich das Bild komplett geladen habe (sprich nach dem screenshot) einen sizeof machen? das müsste doch noch gehen oder?
was anderes könnte ich mir nicht vorstellen, bzw wüsste es nciht besser


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:10 Uhr.
Seite 2 von 5     12 34     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz