Probleme mit SendStream und ReceiveBuf
-
Hallo
warum pruefst du file nicht ab
(zB if ( file )
Ich glaube da kommt dein Fehler herMfG
Klaus
-
Wenn file den Wert 0 enthält, so könnte die Datei, die erstellt werdne soll, nicht erstellt werden.
Darauf mußt du prüfen.
-
Burkhi schrieb:
Wenn file den Wert 0 enthält...
Normalerweise sollte der TFileStream-Konstruktor in diesem Fall aber eine Exception werfen.
@HolyCow: Aus Deinen Beiträgen geht nicht so richtig hervor, in welcher Zeile nun genau der Fehler auftritt - beim ReceiveBuf oder beim Write?
Der Code von Burkhi sieht gut aus und sollte erst einmal funktionieren.
Allerdings würde ich die while-Bedingung so schreiben:while (c != -1)Wenn ich die Hilfe richtig verstanden habe, ist es nicht sicher, daß tatsächlich immer die angeforderte Anzahl an Bytes übertragen wird.
-
c = Socket->ReceiveBuf(buf, sizeof(buf));Die Funktion liefert dir zurück, wieviele Zeichen tatsächlich empfangen wurden. Der zweite Parameter gibt die maximale Größe des Puffers an, der die Zeichen aufnehmen soll.
Daraus folgt: 0 <= c <= sizeof(buf)
Wenn c == sizeof(Buf) ist, so können noch weitere Zeichen empfangen worden sein, deshalb die Schleife.
-
Burkhi schrieb:
Daraus folgt: 0 <= c <= sizeof(buf)

Wenn c == sizeof(Buf) ist, so können noch weitere Zeichen empfangen worden sein, deshalb die Schleife.
Hmmm, laut BCB-Hilfe ist gilt -1 <= c <= sizeof(buf). Und -1 wird zurückgegeben, wenn keine Daten übertragen wurden. (Da würde mich so nebenbei mal interessieren, wo der Unterschied zwischen c=-1 und c=0 besteht.)
Das Problem bei Deiner Schleife ist, daß sie prinzipiell beendet wird, wenn c ungleich, also speziell auch kleiner als sizeof(buf) ist. Wird also irgendwo in der Mitte der Übertragung ein Daten-Paket empfangen, dessen Länge kleiner als sizeof(buf) ist, bricht die Schleife ab, obwohl noch nicht alle Daten angekommen sind.
-
Hallo zusammen,
ich habe jetzt etwas weitergearbeitet und die Sendefunktion ist soweit nun komplett richtig .. glaub ich wenigstens.
Diese Funktion sendet mir die komplette Datei, hatte Testhalber einen Zähler drin der die Datenpackete zählte, nur das Empfangen macht noch Probleme.//Anlegen des Streams ... TFileStream* file = new TFileStream(DateiOeffnen->FileName, fmOpenRead); char buf[1024]; //Buffer int c,b; //Testvariabeln //Solange senden bis Buffer nichtmehr voll geschriben wird, //also Datei zu ende ist do { //Auslesen der zu sendenden Informationen b = file->Read(buf,sizeof(buf)); //Senden des Buffers c = DCSocket->Socket->SendBuf(buf,sizeof(buf)); //Falls nicht gesendet werden konnte, also interner Speicher voll war, //solange warten, bis gesendet werden kann while(c == -1) { Delay(10); c = DCSocket->Socket->SendBuf(buf,sizeof(buf)); } } while(b == sizeof(buf));Hatte ihn mal soweit, dass die ersten 61 gesendeten Datenpackete auch ordnungsgemäß empfangen wurden (bei Bildern konnte ich dann z.B. schon einen kleinen Teil erkennen), nach diesen Packeten sprang er jedoch aus der Funktion und nach einigen Sekunden wieder zurück und ich konnte die Datei nicht mehr öffnen und erhielt einen Fehler wie "Kann Datei nicht anlegen".
Hatte alles mögliche versucht, z.B. die Datei mit FileCreate oder mit Fstream anzulegen oder was weiß ich was mir noch so alles eingefallen ist.
Naja langsamm bin ich hier am verzweifeln
Nun ja, die Empfangfunktion sieht nun so aus. Fast wie am Anfang, da ich sie eben einfach mal versucht hab von Beginn an neu zu programmieren, hilf manchmal bei mir.
TFileStream* file = new TFileStream(DateiSpeichern->FileName, fmCreate); char buf[1024]; int c; do { c = Socket->ReceiveBuf(buf, sizeof(buf)); if(c != -1) file->WriteBuffer(buf,sizeof(buf)); Hauptfenster->Mhauptfenster->Lines->Add("-----> " + IntToStr(c)); } while(c != -1); delete file;Ich erhalte jetzt in meiner Testausgabe seltsammerweise sehr oft eine "-1", das dürfte aber wegen der If-Anweisung gar nicht sein.
Nun ja, werde morgen nochmal was dran arbeiten, geh jetzt erstmal was grillen, sonst werd ich noch verrückt
-
Ich bins nochmal ..
So einfach kann es sein, funktioniert jetzt bei mir, endlich

Also, falls es wen interessiert, hier ist der Code nochmal:
Senden:
//Anlegen des Streams ... TFileStream* file = new TFileStream(DateiOeffnen->FileName, fmOpenRead); file->Seek(0,soFromBeginning); char buf[1024]; //Buffer int c,b; //Testvariabeln //Solange senden bis Buffer nichtmehr voll geschriben wird, //also Datei zu ende ist do { //Auslesen der zu sendenden Informationen b = file->Read(buf,sizeof(buf)); //Senden des Buffers c = DCSocket->Socket->SendBuf(buf,sizeof(buf)); //Falls nicht gesendet werden konnt, also interner Speicher voll war, //solange warten, bis gesendet werden kann while(c == -1) { Delay(10); c = DCSocket->Socket->SendBuf(buf,sizeof(buf)); } } while(b == sizeof(buf)); //Löschen des temporären Streams delete file;Empfangen:
1.Ein Filestream wird in der Headerdatei deklariert.class TDatei : public TForm { [...] public: TFileStream* file; [...] };2.Der Stream wird irgendwo im Programm initialisiert
if(DateiSpeichern->Execute()) { DSSocket->Socket->Connections[0]->SendText("senden"); file = new TFileStream(DateiSpeichern->FileName, fmCreate); } else DSSocket->Socket->Connections[0]->SendText("abbrechen");3. Daten werden ohne Schleife in der Read-Funktion abgespeichert.
char buf[1024]; //Buffer int c; //Testvariabel //Daten auslesen und Größe speichern c = Socket->ReceiveBuf(buf,sizeof(buf)); //Falls Daten gelesen in Filestream speichern if(c != -1) file->Write(buf,c);Hmm hätte zwar nicht gedacht, dass es ohne Schleife funktioniert, aber irgendwie geht es bei mir. Jetzt müssen nur noch paar kleiner Abfragen rein und dann solls das gewesen sein.
Naja wie auch immer, habs also doch noch geschafft.Daher vielen Dank an die umfangreiche und freundliche Hilfe.
ThX
Man sieht sich sicher noch, bin mit meinem Programm ja noch nicht fertig

-
P.S.: Beim Senden müssen die Zeilen
c = DCSocket->Socket->SendBuf(buf,sizeof(buf));
durch
c = DCSocket->Socket->SendBuf(buf,b);ersetzt werden.
Bei kleineren Datenpacketen wird sonst der gesammte Buffer, obwohl er keine verwertbaren Daten beinhaltet, gesendet.
-
Hi, kann mir jemand helfen?
Hab HolyCows Code ausprobiert, nur bei mir funzt er nicht!
Der Stream wird gesendet nur nicht richtig empfangen.
Ich sende ein Bild (9.966 Byte), es kommen alle 9.966 Byte an, aber die sind irgend wie leer, denn das Bild kann nicht geladen werden (ins TImage)Senden:
//Anlegen des Streams ... TMemoryStream* file = new TMemoryStream; file->LoadFromFile("1.bmp"); //Image1->Picture->Bitmap->SaveToStream(file); Image2->Picture->Bitmap->LoadFromStream(file); file->Seek(0,soFromBeginning); char buf[1024]; //Buffer int c,b; //Testvariabeln //Solange senden bis Buffer nichtmehr voll geschriben wird, //also Datei zu ende ist do { //Auslesen der zu sendenden Informationen b = file->Read(buf,sizeof(buf)); //Senden des Buffers c = ClientSocket1->Socket->SendBuf(buf,b); //Falls nicht gesendet werden konnt, also interner Speicher voll war, //solange warten, bis gesendet werden kann while(c == -1) { for(int i=0;i<1000000;i++){} c = ClientSocket1->Socket->SendBuf(buf,sizeof(buf)); } } while(b == sizeof(buf)); //Löschen des temporären Streams delete file;Empfangen:
char buf[1024]; //Buffer int c; //Testvariabel //Daten auslesen und Größe speichern c = Socket->ReceiveBuf(buf,sizeof(buf)); //Falls Daten gelesen in Filestream speichern if(c != -1) Stream->Write(buf,c); ListBox1->Items->Add("Recieve"); Caption=Stream->Size; Image1->Picture->Bitmap->LoadFromStream(Stream);Bitte um hilfe!!!!
Gruß FB4

-
HolyCow,
HolyCow schrieb:
char buf[1024]; //Buffer ... c = Socket->ReceiveBuf(buf,sizeof(buf)); ...Hmm hätte zwar nicht gedacht, dass es ohne Schleife funktioniert, aber irgendwie geht es bei mir.
wenn ich das richtig sehe, "funktioniert" Deine Variante nur bei Dateien bis zu einer Größe von 1024 Byte. Ich fürchte, um die Schleife kommst Du nicht herum - so ungefähr (ungetestet):
int bytesReseived(0); do { bytesReseived = Socket->Receive(buffer, bufferSize); inStream->Write(buffer, bufferSize); } while (bytesReseived != -1)
-
Habs jetzt doch hinbekommen!
Trotzdem Danke dschensky!Gruß FB4