Frage zu recv(...)
-
Ich habe gelesen, das recv() nicht garantieren kann, das man das ganze was man empfangen möchte auch auf einmal bekommt. Daher liefert recv den Wert in Byte zurück, der tatsächlich empfangen wurde.
Jetzt habe ich ein Integer versendet:
int *i = new int (12); send(server->connectedSocket,(const char*)i,4,0);das funktioniert auch.
Nun kann ich den Integer folgendermaßen empfangen:
int *i = new int; int laenge=0; while (laenge!=4) { laenge = laenge+recv (s,(char*)i,4-laenge,0); } cout << *i;Nun mein Problem:
Was passiert, wenn z.B nur 3 Byte empfangen wurden.
Dann wird send(...) ja das fehlende Nachladen, bis laenge==4 ist.
Nun wird beim 2. laden dem send(...) ja wieder die Adresse des int *i übergeben.
Dann wird die Funktion ja das erste byte, welches es reingeschrieben hat überschreiben (denke ich zumindest).Dann habe ich mir gedacht ich umgehe das ganze, in dem ich einfach ein char[4] benutze, also so:
char *i = new char[4]; int laenge=0; while (laenge<4) { laenge = laenge+recv (s,i+laenge,4-laenge,0); }Jetzt kann ich angeben, an welche Stelle nachgeladen werden muß (wegen i+laenge)
Das ging ja vorher nicht, da ein +1 ja schon um 4 byte weiterzählt bei int.
Allerdings gelingt es mir jetzt überhaupt nicht mehr das char[4] in ein int umwandeln.
Ich habe schon alles von der Seite
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39488.html
ausprobiert, aber nichts scheint zu funktionieren.Wie lößt man dieses Problem?
-
int i = *(int*)buffer;
-
Danke!!!!!!!!!!!!!!!
-
Ich habe noch eine Frage:
Wie mache ich das denn bei einem nicht primitiven Tadentyp?
Die ersten 4 sind ja die die zeigeradresse. Diese mitzuübertragen ist ja unsinnig. Wenn ich dann aber den char* so umwandle (wie oben beschrieben) überschreibe ich anscheinen auch die Adresse des Objektes was zu Abstürzen führt.
Wie kann ich denn noch diesen Fall lösen?
-
Wie mache ich das denn bei einem nicht primitiven Tadentyp?
genauso falls du mit nicht primitiver tadentyp ein struct meinst.
-
Hallo, ich habe kein Struct, sonden eine Klasse zum versenden verwendet. Das funktioniert soweit auch ganz gut aber das empfangen macht probleme, denn
struct test { int typ: int groesse; int Nutzdaten; //Methoden } Wenn ich jetzt sizeof(test) schreibe, müßte ja eigentlich 12 dabei rauskommen. Es kommt aber 16 herraus. Ich habe schon herausgefunden, dass die ersten 4 byte irgend eine interne Bedeutung haben. Wenn ich diese Mitübertrage und und im neuen struct beim Empfänger mit eintrage, stürzt dieser ab. Ich habe also beim Senden dies nicht mit übertragen: [cpp] test *t = new test(); send(server->connectedSocket,(const char*)t+4,sizeof(t)-4,0);Jetzt kommen beim Empfänger ja nur 12 Byte an. Auch wenn ich diese an die richtige stelle 4-16 eines char[16] kopiere und dann das Strukt wie im vorherigen Beitrag das ist erstelle, überschreibe ich die 4 Byte.
Wie kann ich diese vorher auslesen und dann wieder eintragen?
Oder wie kann ich sonst mit dem problem umgehen?
-
Ich habe jetzt auch struct getestet (wie oben schon ausversehen als code gepostet) aber auch hier sind die ersten 4 byte das Problem
-
du hast bestimmt virtuelle methoden in der klasse/struct? nimm die methoden komplett raus!
-
test t = ((test)buffer + 4);
-
sorry falsche klammerung
test t = (test)(buffer + 4);
-
Ja genau, jetzt funktioniert es Danke!
Aber warum erzeugt Virtuell diese 4 Byte?
Was steht da drin?
-
Da ist ein Pointer auf ein V-Table drin. Das ist ne Tabelle, in der Zeiger auf deine virtuellen Funktionen sind.
-
@ friggler:
Es funktioniert nur die Version ohne Virtuelle Methoden von aaid
Deine funktioniert leider nicht.(Habe ich getestet)Zwar kopierst du die ersten 4 Byte nicht mit, aber dafür kopiert deine Version die 2ten 4 Byte auf die ersten 4 Byte, in der die Informationen von Virtuel steht usw.
Du kopierst so:
4 Byte virtuel 4 Byte typ 4 Byte Laenge 4Byte werte | | | V V V 4 Byte virtuel 4 Byte typ 4 Byte Laenge 4Byte werte
-
Mensch Mensch Mensch... Das sollte doch kein Problem darstellen...
struct test { int typ; int groesse; int Nutzdaten; void* GetDataPtr() { return &typ; } int GetDataSize() { return sizeof(*this)-4; } }; test *t = new test(); send( server->connectedSocket, t->GetDataPtr(), t->GetDataSize(), 0 );Müsste das nicht funktionieren? Und beim Einlesen das selbe?
-
ja stimmt habs völlig verpeilt. ich denke du brauchst memcpy.
test obj;
memcpy((char*)&obj + 4, ..., ...);aber so das ist alles so eine frickelei! an deiner stelle würde ich boost::serialization nutzen.
-
friggler schrieb:
aber so das ist alles so eine frickelei!
Du heißt doch 'friggler'

-
Badestrand schrieb:
struct test { int typ; int groesse; int Nutzdaten; void* GetDataPtr() { return &typ; } int GetDataSize() { return sizeof(*this)-4; } };Müsste das nicht funktionieren? Und beim Einlesen das selbe?
LOOOOOL, Was soll das denn darstellen ?=?

-
CodeFinder schrieb:
LOOOOOL, Was soll das denn darstellen ?=?


Wollte es ja erst so posten:
struct test { int typ; int groesse; int Nutzdaten; ; test *t = new test(); send( server->connectedSocket, &t->typ, sizeof(test)-4, 0 );aber dann dachte ich, dass er es mit eingebauten Funktionen einfacher findet

-
Badestrand schrieb:
aber dann dachte ich, dass er es mit eingebauten Funktionen einfacher findet

OK, ok, sah nämlich sehr utopisch aus
...
BTW: Das sind Methoden, keine Funktionen
.
-
Ist OK,
ich habe die Version ohne virtuel eingebaut und es klappt prima!Danke an alle!