Zitat von
cRayZo:
Erstmal zum Server: stimmt das jetzt so (hoff mal schon, denk aber eher nicht^^)
Nö, alles in Ordnung. Vom Code her wird genau das erreicht, aber ein wenig besserer Stil ist es, wenn man Resourcen-Schutzblöcke einführt. Damit kann man, im Falle eines Fehlers, immernoch sicherstellen, dass alle angelegten Resourcen auch wieder freigegeben werden. Und wenn das Versenden und Empfangen klappt, dann können wir nochmal drüber reden über eine kleine Regel die besagt, dass man versuchen sollte Resourcen immer auf der gleichen Ebene anzulegen wie man sie auch freigibt. Und dagegen widerspricht die MakeScreenShot Routine. Aber das machen wir dann ein andermal.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
Stream: TMemoryStream;
bitmap: TBitmap;
begin
Stream := TMemoryStream.Create;
MakeScreenShot(bitmap);
try
bitmap.SaveToStream(Stream);
finally
bitmap.Free;
end;
Stream.Position := 0;
Serversocket1.Socket.Connections[0].SendStream(Stream);
end;
Zitat von
cRayZo:
und zum Client nochmal: Dass ichs nicht im onread schreiben darf, leuchtet mir ein, logo!
Die Aussage ist so nicht richtig. Du kannst sonstwas im OnClientRead machen, aber das Problem ist einfach folgendes: OnClientRead() wird von dem Socket mehrfach aufgerufen, immer dann, wenn er mal wieder einen Teil der Daten empfangen hat. Du musst diese einzelnen Teile zusammenspielen in den MemoryStream. Von daher muss der Stream ausserhalb des OnClientRead Ereignishandlers angelegt werden (einmalig) und im Ereignishandler schreibst du einfach nur den eben empfangenen Datenteil in den Memorystream. Wenn du alle Daten empfangen hast (also alle Bilddaten), dann kannst du den Stream wieder auslesen lassen von einem Image/Bitmap. Und da haben wir schon ein neues Problem: Woher weiss der Empfänger, wieviel Bytes an Daten kommen bis das Bild komplett ist? Immer wenn er im Ereignishandler ist, weiss er ja nicht ob noch mehr Aufrufe kommen oder ob es der letzte war. Auch weiss er nicht, ob die Daten, die er gerade vom Socket ausgelesen hat, komplett für das aktuelle Bild sind oder ob da schon wieder neue Daten mit dranne hängen. Von daher merkt man schon, dass du vorher ein paar Daten noch übertragen musst - z.B. die Länge der Bilddaten. Damit weiss der Client, aja, es kommen ab nun (nach einlesen dieser Informationen) genau 24245 Bytes an Bilddaten. Mit dieser Information kann der Ereignishandler genau sagen: Ok, alle Daten in den Memorystream schreiben und soviel Bytes sind noch zu empfangen oder halt auch: hey, ich habe alles - ich kann das Bild anzeigen! Um diese Informationen zu übertragen kannst du einfach vorher die Grösse der Daten übermitteln und danach die Bilddaten. Im Endeffekt baust du dir damit aber schon ein kleines Protokoll und genau sowas brauchst du hier auch noch. Wenn du hier mal nach
Protokoll suchst, findest du auch schon genug Beiträge von Leuten mit einem gleichen oder ähnlichen Problem, denen wir schon entsprechend geholfen haben. Dort kannst du dir dann sowas leicht mal abschauen.