Forum: Compiler & IDEs LwIp-Stack: struct pbuf


von zorro (Gast)


Lesenswert?

Auf einem Mikrocontroller setze ich den LwIp-Stack ein. Nun habe ich ein 
Problem mit der Struktur pbuf. Wie kann von einem empfangenem Udp-Frame 
die Information (Nachrichtentext) aus dem Pointer p extrahiert werden ? 
Ich möchte den gesendeten Text in einen string kopieren.

1
void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct 
2
ip_addr *addr, u16_t port)
3
{
4
    if (p != NULL) {
5
        /* send received packet back to sender */
6
        udp_sendto(pcb, p, addr, port);
7
        /* free the pbuf */
8
        pbuf_free(p);
9
    }
10
}

von zorro (Gast)


Lesenswert?

Mir gelingt es immer noch nicht den empfangenen String (Nachricht) aus 
pbuf zu lesen bzw. in einen stringzu kopieren.

von zorro (Gast)


Lesenswert?

Ok, hab gedacht hier sind einige Experten die bereits den LwIp-Stack 
eingesetzt haben.

von Karl H. (kbuchegg)


Lesenswert?

Und wir hatten eigentlich gedacht, dass sich jemand, der sich mit 
Netzwerkprogrammierung beschäftigt ein bischen besser mit C auskennt, um 
wenigstens in der Lage zu sein, die Übungsaufgaben aus der 7-ten Stunde 
C Unterricht lösen zu können. Selbst dann, wenn sie ihm nicht auf einem 
Silbertablett präsentiert werden, sondern im Kontext einer Aufgabe.

Siehe das Kapitel 'Strings' in einem C-Lehrbuch deiner Wahl.

von zorro (Gast)


Lesenswert?

Ich weiss schon wie man mit string umgeht. Mir geht es nur darum wie ich 
nun die Daten (Textnachricht) vom Pointer *p auslesen kann. Nochmals 
sorry wenn ich mich nicht klar ausgedrückt haben sollte.

von Karl H. (kbuchegg)


Lesenswert?

zorro schrieb:
> Ich weiss schon wie man mit string umgeht. Mir geht es nur darum wie ich
> nun die Daten (Textnachricht) vom Pointer *p auslesen kann.

p ist von welchem Datentyp?

Das wird dann ja wohl ein struct pbuf Pointer sein.

Was genau ist denn ein struct pbuf?
Irgendwo in dieser Struktur wird es wohl einen weiteren Pointer zu den 
eigentlichen Daten geben.

UNd dann kopierst du halt Byte für Byte in deinen Zielstring um. Hinten 
nach noch ein 0 Byte ....

.... und fertig.

Was davon ist jetzt so schwer?

Möglicherweise musst du noch einen Cast setzen, je nachdem wie der 
Datenpointer in struct pbuf definiert ist. Ist es das, was dich aus der 
Bahn wirft?

von PittyJ (Gast)


Lesenswert?

Also ich gucke dann immer in die Header-Files, wie eine Struktur
    struct pbuf
definiert ist. Das Header-File müßte bei den Include's mit drinstehen.
Dann kann man an die einzelnen Elemente der Struktur herangehen.

Rein Interesse halber: wie ist denn das definiert??

von zorro (Gast)


Lesenswert?

Genau dies bereitet mir Probleme. Zunächst danke für die Hilfe.

In der payload steht die empfangene Nachricht (die Nachricht lautet 
"Hallo Micro"):
1
char  **buffer;
2
*buffer = (char*)p->payload

Wenn ich nun elementweise auf den buffer zugreifen möchte, dann sehe ich 
das entsprechende Zeichen nicht.

Element 0: *buffer[0] = 'H'
Element 1: *buffer[1] = 'a'

von Karl H. (kbuchegg)


Lesenswert?

zorro schrieb:
> Genau dies bereitet mir Probleme. Zunächst danke für die Hilfe.
>
> In der payload steht die empfangene Nachricht (die Nachricht lautet
> "Hallo Micro"):
>
1
> char  **buffer;
2
> *buffer = (char*)p->payload
3
>
>
> Wenn ich nun elementweise auf den buffer zugreifen möchte, dann sehe ich
> das entsprechende Zeichen nicht.

a) Du musst den String schon umkopieren.
   Den Buffer hast du laut
1
void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct 
2
ip_addr *addr, u16_t port)
3
{
4
    if (p != NULL) {
5
        /* send received packet back to sender */
6
        udp_sendto(pcb, p, addr, port);
7
        /* free the pbuf */
8
        pbuf_free(p);
9
    }
10
}

nur während des Callbacks zur Verfügung. Ganz am Ende dieser 
Beispielfunktion wird ein pbuf_free gemacht. ...free.... bedeutet 
praktisch immer, dass der entsprechende Speicher freigegeben wird und 
recycled wird. D.h. wenn du dir nachher den Speicher ansiehst, kann da 
schon wieder ganz was anderes drinnen stehen.

b) in der pbuf Struktur wird es ja auch noch sowas wie eine Längenangabe 
geben. Passt die irgendwie zu dem was du geschickt hast? Hast du dir 
schon mal den kompletten Buffer angesehen?

c) Nur weil du einen kompletten String beim Sender weggeschickt hast, 
heisst das noch lange nicht, dass du den String auch in einem Rutsch vom 
IP-Stack wieder kriegst. Da liegen ein paar Schichten dazwischen, welche 
die Daten in Blöcke aufteilen.

d) Das Problem kann ja auch beim Sender liegen.

Also schau dir mal den Buffer genauer an, was denn da so alles drinnen 
steht.

von PittyJ (Gast)


Lesenswert?

Hm, ein gutes C-Buch mit Beschreibung von Pointern könnte helfen?


Also, ich lasse immer die Doppelpointer weg.
Bei mir wäre es
 char  *buffer;
 buffer = (char*)p->payload

und dann würde stehen
Element 0: buffer[0] = 'H'
Element 1: buffer[1] = 'a'

von zorro (Gast)


Lesenswert?

Nun ich habs geschafft die ankommenden Daten in ein Array zu kopieren:
1
char  *buffer;
2
buffer = (char*)p->payload;

(Mit Wireshark sehe ich auch die ankommenden Daten)

von Karl H. (kbuchegg)


Lesenswert?

zorro schrieb:
> Nun ich habs geschafft die ankommenden Daten in ein Array zu kopieren:
>
>
1
> char  *buffer;
2
> buffer = (char*)p->payload;
3
>

Ganz sicher nicht.
Das kopiert keine Daten.

Womit wir wieder beim C-Lehrbuch wären.

Lies es mir von den Lippen ab:
Man kann die Daten eines Arrays nicht in einem Rutsch umkopieren. Arrays 
sind Bastarde, die sich in C anders verhalten als alle anderen 
Datentypen. Oder warum denkst du dass es Funktionen wie strcpy oder 
memcpy gibt?

Was du hier gemacht hast: Du hast dir eine Kopie des Pointers auf die 
Daten gemacht. Ein Pointer auf Daten ist aber nicht die Daten selber.
Wenn du in einer Bibliothek die Notiz "Buch steht im Regal 5/Standplatz 
8" kopierst, dann hast du dir die Notiz kopiert. Du hast aber nicht das 
Buch selber kopiert. Dazu musst du schon zu besagtem Regal hingehen und 
das BUch Seite für Seite auf den Kopierer legen.

von Bronco (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Dazu musst du schon zu besagtem Regal hingehen und
> das BUch Seite für Seite auf den Kopierer legen.

Denn wie Karl-Heinz oben schon erwähnt hat, wird mit
> /* free the pbuf */
>
>         pbuf_free(p);
das Buch aus dem Regal genommen und verbrannt.

D.h. kopiere das Buch, solange es noch im Regal steht, sonst findest Du 
da nur einen leeren Schuber vor, und Du wirst den leeren Schuber nicht 
als solchen erkennen!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.