Das Leidige Thema: Socket->ReceiveBuf und SendStream
-
Und wo genau ist das Problem ? Das scheint mir keine Indy Komponente zu sein womit du arbeitest. Wie kommst du auf die Idee das nur die Größe empfangen würde ? Zeig mal Code
-
Arg mist, hab mich falsch ausgedrück:
Benutze TClientSocket und nicht Indy. (Benutze nur sonst seit ich Indy verstehe, nur indy, gewohnheit machts :))Code habe ich nicht so wirklich.
Hab mir das (wieder mal)viel zu einfach gedacht:
wollte mittels ServerSocket1->Socket->Connections[0]->SendStream(Stream); senden und dann in OnRead beim Clienten mittels Socket->ReceiveBuf empfangen.
Und genau da ist das Problem, denn ich weiss garnicht, wie ich dem PC klarmache, dass er den Stream 'Stream' empfangen soll (und später in einem TImage laden soll) bzw. welche Parameter ich für ReceiveBuf benutze.Greez,
J0
-
Schonmal in die online-Hilfe zu ReceiveBuf geschaut ??????
das ist doch ganz easy, du musst nur einen buffer übergeben und die anzahl an bytes die er versuchen soll zu lesen ( wenn du mehr angibst liest er trotzdem nur die die anstehen - die anzahl der wirklich gelesenen bytes wird zurückgegeben). Dann kopierst du den buffer in einen stream und kannst den stream vom einem image aus mit LoadFromStream laden. Einfach mal in die Hilfe schauen[ Dieser Beitrag wurde am 24.01.2003 um 19:06 Uhr von etechniker editiert. ]
-
Äh tja, ganz dumme Frage:
wo is die Online Hilfe?
Entweder bin ich zu dumm dazu die zu finden, zu müde, oder einfach unbegabt
habs bisher mitvoid __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket) { Socket->ReceiveBuf(Stream,Socket->ReceiveLength()); Form2->Screenshot->Picture->Bitmap->LoadFromStream(Stream); } //--------------------------------------------------------------------------- //Und mit: void __fastcall TForm1::Button1Click(TObject *Sender) { Image1->Picture->Bitmap->SaveToStream(Stream); Server->Socket->Connections[0]->SendStream(Stream); //Bzw.SendBuf(Stream,50000); } //---------------------------------------------------------------------------
versucht, nur leider passiert beim ersten mal garnichts, und beim zweiten mal kommt fehler:
Zugriffverletzung bei Adresse 6E6E6F43. Lesen von Adresse 6E6E6F43 (Bei SendStream) und bei SendBuf kommt Fehler: 'auf API 'send''.
könnt ihr mir nochmal helfen/link zur onlinehilfe geben.
N8 all,J0
<edit>Keine Leerschläge zwischen type und ="C++"!</edit>
[ Dieser Beitrag wurde am 24.01.2003 um 23:20 Uhr von junix editiert. ]
-
Dann solltest du die Sache überschlafen und dann nochmals angehen
Wie man die Hilfe benutzt solltest du dir schon beibringen.
Wie ich sagte, du brauchst zum lesen einen zwischen-puffer den du dann in den Stream schreibst (mit Write). Du kannst auch mit ReceiveLength die länge des benötigten Puffers rausfinden.
Ich bin übrigens dabei ein ganz Ähnliches Programm zu schreiben. Ich würde dir vorschlagen das Bild vor dem Versenden in ein jpeg umzuwandeln. Und wenn du bewegte Bilder übertragen willst dann solltest du nur die Änderung zum vorherigen Bild übertragen
So, genug Futter für heute, schaus dir mal an.P.S. : statt des streams in ReceiveBuffer nimm ein char*, nicht vergessen vorher speicher zu reservieren und nachher wieder freizugeben.
-
Die Onlinfe-Hilfe ist wenn du F1 drückst z.B. (:
Was dein Beispiel anbelangt., Du darfst heir nicht eifach den Zeiger auf die TStream-Instanz übergeben! Du musst einen Extrapuffer bereitstellen. Also sowas:
BYTE *Buffer_BYTEp = new BYTE[CharsToReceive_int]; Socket->Receive(Buffer_BYTEp, CharsToReceive_int); Stream->Write(Buffer_BYTEp, CharsToReceive_int); delete [] Buffer_BYTEp;
... ich hoffe du kannst an diesem Beispiel einige Erkenntnisse gewinnen (:
-junix
-
Sag ich doch... Jaja, die Moderatoren dürfen auf einmal Komplettlösungen bieten...
-
Hat nix mit Komplettlösung zu tun. Ausserdem ist hier eine eindeutige Bemühung seitens <J0> feststellbar. Es handelt sich ja auch nicht um eine Komplettlösung. Er muss sie immernoch für sich direkt adaptieren.
Ich wollte dich damit auch nicht untergraben. Dein und mein Posting sind quasiparallel entstanden. Ich hatte mir nur mehr Zeit gelassen beim posten.
-junix
-
fühle mich nicht untergraben
-
ich bekommst noch immer nicht hin (*langsam-verzweifel*):
Hier mal der code:
Senden mit dem Clienten über SendStream:
ClientSocket1->Socket->SendText("stream"); Image1->Picture->Bitmap->SaveToStream(Stream); Stream->Position = 0; ClientSocket1->Socket->SendStream(Stream);//,Stream->Size); //Stream->Position = 0; Image2->Picture->Bitmap->LoadFromStream(Stream);
Aber jetzt kommt dieser Fehler
Im Projekt Project2.exe ist eine Exception der Klasse EAccesViolation aufgetreten. Meldung:
'Zugriffsverletzung bei Adresse 6E6E6F43. Lesen von Adresse 6E6E6F43'.Wenn ich´s mit SendBuf versuche kommt am Server dieser Fehler :
Ungültiges Bitmap Format.Stream->Position = 0; ClientSocket1->Socket->SendText("stream"); Image1->Picture->Bitmap->SaveToStream(Stream); Stream->Position = 0; ClientSocket1->Socket->SendBuf(Stream,Stream->Size); //Stream->Position = 0; Image2->Picture->Bitmap->LoadFromStream(Stream);
Empfangen läuft so:
Stream->Position = 0; if(stream == false) command = Socket->ReceiveText(); if(stream == true) { stream = false; int CharsToReceive_int = Socket->ReceiveLength(); BYTE *Buffer_BYTEp = new BYTE[CharsToReceive_int]; Socket->ReceiveBuf(Buffer_BYTEp, CharsToReceive_int); Stream->Position = 0; Stream->Write(Buffer_BYTEp, CharsToReceive_int); Image1->Picture->Bitmap->LoadFromStream(Stream); delete [] Buffer_BYTEp; } if(command == "stream") { Form1->Caption = "Stream"; stream = true; } Form1->Caption =""; Anweisungen->Text = command;
Erklärung: Als erstes wird Text gesendet und dem sever klar gemacht, dass als nächstes ein Stream kommt.
Beim Empfang wird, wenn nicht vorher schon gesagt wurde, als erstes der empfangene Text in nen AnsiString kopiert.(AnsiString command) Wenn ein Stream angekündigt wurde, dann kommt abfrage für den Stream. Und dadrin kommt der Fehler.
Woran kann das liegen?
Bin für jede Hilfe froh!
J0 (hei, das reimt sich :))
[ Dieser Beitrag wurde am 21.02.2003 um 16:52 Uhr von J0 editiert. ]
[ Dieser Beitrag wurde am 21.02.2003 um 17:41 Uhr von Jansen editiert. ]
-
Original erstellt von J0:
**Image2->Picture->Bitmap->LoadFromStream(Stream);Aber jetzt kommt dieser Fehler
Im Projekt Project2.exe ist eine Exception der Klasse EAccesViolation aufgetreten. Meldung:
'Zugriffsverletzung bei Adresse 6E6E6F43. Lesen von Adresse 6E6E6F43'.**Hatten wir das nicht gerade? Tritt der Fehler auch auf, wenn im Image vorher schon ein Bild geladen war?
-
Der Fehler tritt immernoch auf (ich benutze kein JPG (kommt später) da ich zum Testen BMP praktischer finde, kA warum)
J0
-
Bei mir gibt's die LoadFromStream-Exception bei einem "uninitialisierten" TImage auch bei BMP-Streams, deshalb meine Frage.
Hast du mal den Zwischenschritt über ein TBitmap probiert?
PS. Alternativ kannst du die "Initialisierung" auch vornehmen, indem du Image2->Picture->Bitmap->Width/Height auf mindestens 1 setzt, bevor du den Stream lädst. Das ist wohl die eigentliche Ursache des Problems.
[ Dieser Beitrag wurde am 21.02.2003 um 17:22 Uhr von Jansen editiert. ]
-
ich habe im Builder ein TImage erstellt.
Dann habe ich da (immernoch im Builder) eine gültige BMP-Datei geladen.
Und jetzt kommt die Fehlermeldung.Das ist doch über den Umweg oder? oder meinst du wie in dem Link, bloss kein JPG sondern TBitmap?
Ich werd´s mal so versuchen,
J0
-
also: habs jetzt so gemacht:
if(stream == true) { stream = false; int CharsToReceive_int = Socket->ReceiveLength(); BYTE *Buffer_BYTEp = new BYTE[CharsToReceive_int]; Socket->ReceiveBuf(Buffer_BYTEp, CharsToReceive_int); Stream->Position = 0; Stream->Write(Buffer_BYTEp, CharsToReceive_int); Stream->Position = 0; Graphics::TBitmap *hallo = new Graphics::TBitmap; /*Hier kommt gleicher Fehler*/ hallo->LoadFromStream(Stream); Image1->Picture->Graphic = hallo; delete [] Buffer_BYTEp; }
Heisst das denn nicht,dass der(die oder das?) Stream nicht richtig rübergekommen ist?
J0[ Dieser Beitrag wurde am 21.02.2003 um 18:39 Uhr von J0 editiert. ]
-
Ich bin so ungeduldig ;((
kann mir jemand sagen wo der Fehler liegt?
Ich will dieses Programm endlich fertig kriegen
Bitte!!
Schonmal Ultragroßes Danke,
J0
-
Kann es nicht auch daran liegen, dass vorher irgendwelche Connections 'freigegeben' werden müssen? ich benutze nirgendwo Open():
Aber texte kann ich 1a verschicken...J0
-
öh äh open benutzt du nicht? Natürlich musst du die Sockets erst öffnen! Was liefert eigentlich SendStream() zurück?
-junix
-
ES GEHT! ICH DANKE EUCH ALLEN HERZLICHST!!
ES GEHT!!! JUPPI!!
Ich hab´s jetzt mir SendStream gemacht, das Bild kommt an, ABER:
es kommen Zugriffsverletzungen ohne Ende, und das Programm ist nicht mehr nutzbar (Client).Ich weiss net ob das umbedingt neuer Thread muss, da es ja mit dem Prob zu tun hat...
NOCHMAL DANKE!!!
J0
-
OK: ICH HABS HINBEKOMMEN!
Wenn ich vom ServerSocket aus sende, kommt das Bild 1a an!
DANKE NOCHMAL AN ALLE DIE MIR GEHOLFEN HABEN!
J0