Wie wird ein Buffer bei Socket-Bild-Transfer richtig verwendet ?
-
hallo Jansen,
vielen Dank für dein Beispiel
...du wirst es nicht glauben, aber bei mir passiert garnix, wenn ich auf's Knöpfchen (Button1) drücke ???
hier der nach deinen Vorgaben umgebaute Code, vielleicht weisst du ja woran das liegt ?
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "Jpeg.hpp" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; TMemoryStream *mem=new TMemoryStream(); int img_size=0; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { TJPEGImage *jpgsend= new TJPEGImage(); TMemoryStream *memsend=new TMemoryStream(); jpgsend->LoadFromFile(".\\marikobild.jpg"); jpgsend->SaveToStream(memsend); img_size = memsend->Size; char ch[5]; memsend->Seek(0, soFromBeginning); memsend->Read(ch, 4); memsend->Seek(0, soFromEnd); memsend->Write(ch, 4); memsend->Seek(0, soFromBeginning); memsend->Write(&img_size, 4); img_size = 0; memsend->Seek(0, soFromBeginning); ClientSocket1->Socket->SendBuf(memsend->Memory,memsend->Size); delete jpgsend; delete memsend; } //--------------------------------------------------------------------------- void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket) { int bufsize = Socket->ReceiveLength(); BYTE *Buffer = new BYTE[bufsize]; mem->Seek(0, soFromEnd); Socket->ReceiveBuf(Buffer, bufsize); mem->Write(Buffer, bufsize); delete [] Buffer; if (img_size == 0) { mem->Seek(0, soFromBeginning); mem->Read(&img_size, 4); } else if (mem->Size == (img_size + 4)) { TJPEGImage *jpg= new TJPEGImage(); char ch[5]; mem->Seek(-4, soFromEnd); mem->Read(ch, 4); mem->Seek(0, soFromBeginning); mem->Write(ch, 4); mem->Size -= 4; mem->Seek(0, soFromBeginning); jpg->LoadFromStream(mem); Image1->Picture->Assign(jpg); delete jpg; delete mem; } } //---------------------------------------------------------------------------
-
Tja, hier funktioniert dein Code einwandfrei.
Bist du schon mal durchgesteppt? Wird zB. am Anfang das Bild überhaupt geladen, wird die img_size richtig geschrieben und ausgelesen oder wird die "else if"-Abfrage jemals wahr?
-
es hängt an der else-if Abfrage...
wenn ich nach dem abholen der img_size
ein ShowMessage(mem->Size);
setze, wird in 8192er Schritten runtergezählt???if (img_size == 0) { mem->Seek(0, soFromBeginning); mem->Read(&img_size, 4); } ShowMessage(mem->Size);
-
ich habe jetzt fast die ganze Nacht an diesem blöden Problem gesessen
--> so langsam verzweifele ich, könnt ihr mir vielleicht noch einmal weiterhelfen ?- das laden des Bildes (auf ClientSeite) funktioniert
- die Dateigrösse wird auch richtig übergeben
-> das Problem ist, dasif (mem->Size == (img_size + 4))
nie wahr wird...
durhc einShowMessage(mem->Size);
habe ich gesehen, das seltsamerweise die Streamgrösse kleiner wird, könnt ihr mir das erklären ?
int img_size=0; TMemoryStream *mem=new TMemoryStream(); void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket) { int bufsize = Socket->ReceiveLength(); BYTE *Buffer = new BYTE[bufsize]; mem->Seek(0, soFromEnd); Socket->ReceiveBuf(Buffer, bufsize); mem->Write(Buffer, bufsize); delete [] Buffer; ShowMessage(mem->Size); if (img_size == 0) { mem->Seek(0, soFromBeginning); mem->Read(&img_size, 4); } if (mem->Size == (img_size + 4)) { TJPEGImage *jpg= new TJPEGImage(); char ch[5]; mem->Seek(-4, soFromEnd); mem->Read(ch, 4); mem->Seek(0, soFromBeginning); mem->Write(ch, 4); mem->Size -= 4; mem->Seek(0, soFromBeginning); jpg->LoadFromStream(mem); Image1->Picture->Assign(jpg); delete jpg; delete mem; } }
-
Hi,
vielleich wird die esle if
nie war weil die img_size keine daten von dem Stream bekommt.if (img_size == 0) { Stream->Seek(0, 0); Stream->Read(&img_size, 4); } ShowMessage(img_size); // <-- img_size ist bei mir immer 0 ? o_O ?
-
leider nein, bei mir steht in img_size die Grösse des Bildes...
--> trotzdem danke für den Versuchhier nochmal der ClientCode
void __fastcall TForm1::Button1Click(TObject *Sender) { TJPEGImage *jpgsend= new TJPEGImage(); TMemoryStream *memsend=new TMemoryStream(); jpgsend->LoadFromFile(".\\testbild.jpg"); jpgsend->SaveToStream(memsend); img_size = memsend->Size; char ch[5]; memsend->Seek(0, soFromBeginning); memsend->Read(ch, 4); memsend->Seek(0, soFromEnd); memsend->Write(ch, 4); memsend->Seek(0, soFromBeginning); memsend->Write(&img_size, 4); img_size = 0; memsend->Seek(0, soFromBeginning); ClientSocket1->Socket->SendBuf(memsend->Memory,memsend->Size); delete jpgsend; delete memsend; }
-
Ich denke, das hatte gestern schon funktioniert (vor dem Editieren deiner Nachricht ;))?
Nach dem Abarbeiten diese Abschnittes
mem->Seek(0, soFromEnd); Socket->ReceiveBuf(Buffer, bufsize); mem->Write(Buffer, bufsize);
ist der Stream kleiner als zu Beginn des Abschnittes?
Schwer zu glauben, insbesondere, da die Streamgrösse dann ja schon nach dem ersten Lesen kleiner als Null sein müsste.
-
schwer zu glauben aber wahr...
versuche mal den Abschnitt so auszuführen.mem->Seek(0, soFromEnd); Socket->ReceiveBuf(Buffer, bufsize); mem->Write(Buffer, bufsize); delete [] Buffer; ShowMessage(mem->Size);
dann erhalte ich eine immer kleiner werdende mem->size ???
p.s.
ich hatte gestern meinen Eintrag editiert, da ich zum Test ob das laden auf Clientseite funktioniert ein zweites TImage angelegt hatte und in meinem Übereifer gedacht hatte, es wäre das erste *schäm*
-
kann mir jemand erklären warum
BYTE *Buffer = new BYTE[bufsize]; Stream->Seek(0, 2); // <-- warum hier auf das Ende? des Streams gezeigt wird? Socket->ReceiveBuf(Buffer, bufsize);
cya
-
damit man nicht die schon geschriebenen Daten im Stream überschreibt
...mein Problem hängt wohl eher mit meinem Netzwerk zusammen, als mit der Software, da es in einem anderen Netz einwandfrei läuft...
Demnach danke ich euch allen und bin nun fast ein Experte in Sachen Stream & Co
-
Nochml zum kleiner werden: du hast Recht, das ShowMessage zählt eigenartigerweise wirklich rückwärts.
Wenn du stattdessen ein Memo1->Lines->Add(mem->Size); zur Kontrolle verwendest sollten aber die korrekten (ansteigenden) Werte ausgegeben werden, die sich ja auch per Debugger verifizieren lassen.
-
ich habe jetzt herausgefunden, das das Problem damit zusammenhängt, das ich Server und Client lokal auf einem Rechner versucht habe zu verbinden.
Jetzt habe ich Server und Client getrennt --> also zwei Programme geschrieben und Server und Client auf zwei verschiedenen Rechner gestartet...
Das Ergebnis war verblüffend = es läuft ohne Mucken