Dynamisches char im struct
-
jup, ganz genau. Ich hätte nicht erwartet, dass das einen Unterschied macht.
-
germangeek schrieb:
jup, ganz genau. Ich hätte nicht erwartet, dass das einen Unterschied macht.
einen gewaltigen unterschied macht das. tcp schiebt alles empfangene in einen FIFO aus dem der user sich das häppchenweise holen kann. bei udp bekommste pakete und wenn man nicht alles abholt ist der rest weg. guckst du: http://www.c-worker.ch/tuts/udp.html
-
Verdammt! Ich muss an der Stelle leider bei UDP bleiben.
Gibt ess eine Möglichkeit das zu umgehen? Ansonsten hoffe ich ja noch auf jox mit einer genialen Lösung
-
mach ein recv oder recvfrom unter angabe der vollen länge:
unsigned char buffer[1500]; ... recv_result = recv (socket, buffer, sizeof(buffer), 0); ...
dann haste alle daten.
-
Ich bekomme ja nun aber gerade einen struct geschickt! In diesem stehen am Anfang mehrere Zahlen, dann kann ich doch nicht einfach alles in einen char schreiben, oder doch?
-
struct data *test = (struct data*) buffer; printf("Laenge der Daten: %d\n", test->laenge);
-
Da gibt aber den Fehler:
error: dereferencing pointer to incomplete type
-
germangeek schrieb:
Ich bekomme ja nun aber gerade einen struct geschickt! In diesem stehen am Anfang mehrere Zahlen, dann kann ich doch nicht einfach alles in einen char schreiben, oder doch?
Doch, würde ich so auch versuchen. Einfach einen Buffer mit der maximalen Länge vorsehen und dann alles einlesen:
unsigned char buffer[MAX_LENGTH]; struct data *test; rc = recvfrom(s, buffer, sizeof(buffer), 0, 0, 0); test = (struct data *) buffer; if (rc < (sizeof(test->zahl)+sizeof(test->zahl2)+sizeof(test->laenge)) => Error else if (rc != (test->laenge+sizeof(test->zahl)+sizeof(test->zahl2)+sizeof(test->laenge))) => Error else => alles korrekt empfangen ...
Aber Achtung: UDP ist ein ungesichertes Protokoll. Es ist nicht sichergestellt, dass alle Daten rüberkommen! Deswegen der Vergleich: "rc != test->laenge"
-
germangeek schrieb:
Ich bekomme ja nun aber gerade einen struct geschickt! In diesem stehen am Anfang mehrere Zahlen, dann kann ich doch nicht einfach alles in einen char schreiben, oder doch?
das geht (im idealfall so wie lordJax vorschlägt, aber unter vorbehalt, gleicher compiler, gleiche architektur auf beiden seiten usw.). rückgabewert von recv ist dann die paketlänge (also alle struct members und der datenblock)
-
jox schrieb:
Aber Achtung: UDP ist ein ungesichertes Protokoll. Es ist nicht sichergestellt, dass alle Daten rüberkommen! Deswegen der Vergleich: "rc != test->laenge"
nee, wenn das paket ankommt dann ist alles in ordnung. man braucht z.b. keinen crc anhängen oder ähnliches. was passieren kann ist, dass pakete ganz ausbleiben (entweder sie schafften's nicht über's netz oder wurden von lokalen komponenten weggeschmissen wegen negativen integritäts-checks)
-
Okay, dann noch zwei (hoffentlich) letzt Fragen:
1.) Warum gibt es in test = (struct databuffer; den Fehler:
error: incompatible types in assignment
EDIT: 1.) hat sich erledigt. Mein Fehler!
2.) Wie bekomme ich es dann hin, dass meine struktur wieder korrekt ist?
Ich lege mir einen neuen struct data an und kopiere die int's rüber. Wie aber läuft das mit dem char? Das 'echte' char ist ja kleiner als es aktuell im buffer drin liegt!
-
Wieso musst Du die Struct nochmal kopieren? Nimm test, welches auf Buffer zeigt, und gut ist.
Die Daten hinten kannst Du auch mit daten[16] ansprechen, lass Dich nicht davon irritieren, dass die vermeintliche Länge nur 1 ist.
-
germangeek schrieb:
2.) Wie bekomme ich es dann hin, dass meine struktur wieder korrekt ist?
Ich lege mir einen neuen struct data an und kopiere die int's rüber. Wie aber läuft das mit dem char? Das 'echte' char ist ja kleiner als es aktuell im buffer drin liegt!Du brauchst die Strukturelemente nicht zu kopieren, lasse einfach Deine Struktur auf den Anfang des Buffers zeigen (siehe mein Code-Beispiel oben). char[1] ist nur ein "Platzhalter". Du kannst auf die einzelnen Elemente des Array anschließend normal auch mit Indices >0 zugreifen.
-
Wie geben ich denn jetzt z.B. die zahlen aus?
Jetzt bin ich verwirrt...printf("Laenge der Daten: %d\n", test->laenge)
So geht es nämlich nicht.
-
germangeek schrieb:
2.) Wie bekomme ich es dann hin, dass meine struktur wieder korrekt ist?
ich finde du solltest von diesem struct trip runterkommen. definier' dein paketformat als eine folge von 'octets' z.b.
anzahl | bedeutung 2 blubb 2 blah 2 länge des datenblocks 0..x datenblock
...und dann legste noch die byte order fest (little endian wär sinnvoll für x86 kisten)
damit gehste vielen problemen aus dem weg
-
Doch, genau so.
(Tipp: "Geht nicht" ist keine ausreichende Fehlerbeschreibung)
-
Ich verwende den Code von jox und versuche anschließend etwas auszugeben.
printf("Laenge der Daten: %d\n", test->zahl);error: dereferencing pointer to incomplete type
-
Dann kennt Dein Compiler struct data zu dem Zeitpunkt nur als Vorwärtsdeklaration.
struct test data2;
dürfte an der Stelle auch nicht gehen.
-
Ein fettes DANKESCHÖN an alle die mir hier weitergeholfen haben!
Dank euch funktioniert es nun.