Forum: Compiler & IDEs uIp - Daten größer als 1,5kB empfangen


von Josef K. (josefk)


Lesenswert?

Man bin ich heute fragewütig.

Mich würde interessieren was passiert, wenn mir meine Gegenstelle ein 
sehr großes Datenpacket schickt. Sprich, wenn mir, sagen wir mal, 10 mal 
ein 1,5kB Packete entgegen kommen. Mein ENC28J60 hat einen Puffer von 
8k, wenn ich das richtig sehe, und mein Programm empfängt die Packete 
vom ENC.
Aber was macht uIP? Der uip_data Puffer ist ja nicht groß genug, aber 
die Daten müssen aus dem ENC raus. Die Daten müssen also auf den µC aber 
der Puffer dort ist evtl. nicht große genug, um alle zu speichern.
Was passiert dann?

Verwirrend verwirrend....

von Simon K. (simon) Benutzerseite


Lesenswert?

Josef Kaeufl wrote:
> Man bin ich heute fragewütig.
>
> Mich würde interessieren was passiert, wenn mir meine Gegenstelle ein
> sehr großes Datenpacket schickt. Sprich, wenn mir, sagen wir mal, 10 mal
> ein 1,5kB Packete entgegen kommen. Mein ENC28J60 hat einen Puffer von
> 8k, wenn ich das richtig sehe, und mein Programm empfängt die Packete
> vom ENC.
Nein, der ENC28J60 hat 8kiB RAM, wovon in der Regel 2kiB als Sendepuffer 
reserviert werden und 6kiB als Empfangspuffer (genaue Werte musst du in 
deinem ENC28J60 Treiber nachschauen). Das heißt, dass man im Prinzip 
etwa 4 Full-Size (1514 Byte) Ethernet Frames empfangen kann, auf einen 
Schlag.

> Aber was macht uIP? Der uip_data Puffer ist ja nicht groß genug, aber
> die Daten müssen aus dem ENC raus. Die Daten müssen also auf den µC aber
> der Puffer dort ist evtl. nicht große genug, um alle zu speichern.
> Was passiert dann?
Dein ENC28J60 Treiber sorgt dafür, dass immer ein Paket aus dem Puffer 
gelesen wird und an den uIP Stack weitergereicht wird. Also maximal 1514 
Byte.

von Josef K. (josefk)


Lesenswert?

Also wenn mir jemand 3kB Daten schickt, dann kann ich diese nicht am 
Stück bearbeiten, insofern ich keine Vorkehrungen treffe diese 2 Packete 
in meinem µC zwischen zu speichern?!

Naja, das war zu erwarten. Blöd ist das aber schon, da es ja sein kann, 
dass die 3kB ungünstig voneinander getrennt wurden. Bei mir ist es so, 
dass mir 8Byte Befhlsblöcke geschickt werden. Wenn da jemand mal 3kB / 
8B Befehle schickt, dann ist die Wahrscheinlichkeit groß, dass ich mit 
meinem Parser scheitere. Das sind keine guten Nachrichten :)

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin,

> ...Wenn da jemand mal 3kB /
> 8B Befehle schickt, dann ist die Wahrscheinlichkeit groß, dass ich mit
> meinem Parser scheitere. Das sind keine guten Nachrichten :)
>
nun, sagen wir mal so, du brauchst am Anfang des 3k/8k-Datenpakets halt 
eine eindeutige Kennung, die dein Parser kennt. Brauchst du doch 
eigentlich sowieso, sonst weist du doch garnicht was du mit den Daten 
machen sollst, oder...?

Im MC-Programm mußt du dann schauen, ob am Anfang diese Kennung steht. 
Wenn ja, dann ist es ein neues Paket. Wenn in diesem Paket nicht alle 
Daten enthalten sind, muß man sich dies merken (in der entsprechenden 
Struktur der jeweiligen Connection). Solange keine Pakte mit einer neuen 
Kennung kommen, gehören halt die Daten noch zum vorhergehenden Paket...

Soweit ich mich erinnern kann, ist dieser Mechanismus auch in einigen 
uip-Beispielen beschrieben.

Uwe

von Dirk B. (sharandac)


Lesenswert?

Ja, deshalb will man eigentlich auch nicht uIP benutzen, denn dort wird 
das sequenzielles lesen das TCP-Datenstrom nicht unterstützt, der User 
muss sich selber darum kümmern. Damit wird einem beim verarbeiten ein 
ganz schöner Stein in den Weg gelegt, da man sich immer noch selber 
darum kümmern muss und so das pharsen von Headern oder anderen Daten 
sehr schwer wird. Andere TCP/IP-Stacks funktionieren da wesentlich 
durchdachter und befreien den Programmierer von genau solchen Problemen.

CA Dirk

von Uwe B. (boerge) Benutzerseite


Lesenswert?

Geschmackssache... Ich benutze bis jetzt nur uip und kenne andere Stacks 
nicht so genau, um mir ein Urteil bilden zu können. Aber irgend wann 
wird dir auch bei anderen Implementierungen soetwas auf die Füsse 
fallen, wenn die Datenpakete groß genug werden...

Klar es gibt bei jeder Implenementierung Vor- und Nachteile. Zu den 
Vorteilen von uip zähle ich die einfache (und übersichtliche) Einbindung 
in seine Applikation (oder umgekehrt, je nach dem, wie man es sehen 
will), was ich bei anderen Stacks noch nicht so gesehen habe.

Uwe

von Dirk B. (sharandac)


Lesenswert?

Ja sicher. Aber Sinn eines Stacks sollte sein den Programmierer 
weitestgehend genau von solchen Aufgaben/Problemen zu entlasten. Und das 
ist bei uIP nicht leider nicht gelungen, so das der Programmierer sich 
dann doch wieder intensiv mit Netzwerkdingen beschäftigen muss. Der 
große Vorteil von uIP ist das er sehr klein ist, dies ist aber durch 
fehlende Funktionen auch sein großer Nachteil.
Aber das wie du schon sagtest, geschmackssache.
Ich für mich habe aber festgestellt das bei uIP dadurch die eigentliche 
Aufgabe verdrängt wird durch andere Probleme. Ich hatte mit diesen 
Problemen sehr stark zu kämpfen und habe auch lwIP ausprobiert, was aber 
keine wesentlich Besserung brachte.

von Simon K. (simon) Benutzerseite


Lesenswert?

Ne, moment mal Leute. Ich glaube Josef vertut sich da.

Wie sendest du denn die 3kiB am PC? Wenn du 3kiB sendest, dann wird der 
"Datenblock" vom Windows-Stack automatisch in Pakete aufgeteilt.

Bei UDP Paketen beträgt die maximale Größe die in der Windows Registry 
eingetragene MTU (minus Ethernet, IP und UDP header).

Wenn du über TCP sendest, dann wird beim Öffnen der Verbindung mit dem 
uip-Stack die Maximum Segment Size übertragen. Das heißt, beim Öffnen 
der Verbindung teilen beide Gesprächspartner ihrem Gegenüber mit, wie 
groß die Pakete sein dürfen, die derjenige empfangen kann. uip leitet 
die MSS von der Puffergröße ab, die in der Konfiguration eingestellt 
ist.

Es gibt also keine 3kiB großen Netzwerkpakete (ich glaube mit IPv6 
werden die Jumbo-Frames erst möglich..?). Die maximale Maximum 
Transmission Unit ist in IPv4 Netzwerken max. 1514 bzw. 1518 (mit 
LowLevel CRC-Checksum) Byte. Fragmentiert wird so oder so.

Wenn du dieses große Paket (was ja zerteilt wird) an einen anderen PC 
schickst, dann wird dieser das Paket zusammenbauen, bis es wieder 3kiB 
beträgt und an deine Anwendung weiterreichen. Das geht aber nicht, da 
der uip-Stack das nicht (oder nur mit nicht gut getestetem "Addon") 
unterstützt, da er ganz einfach für kleine Speichergrößen geschrieben 
ist.

So, jetzt gilt, wie bereits gesagt, dass du deine TCP/UDP Applikation 
auf dem uip-Stack so schreiben musst, dass es mit der Paketweisen 
Behandlung klar kommt. Einen einfachen POST-Parser habe ich in meinem 
MikroWebServer programmiert. Es werden Statusvariablen im "AppState" des 
jeweiligen Sockets hinterlassen, die den Parser, egal wo er anfängt zu 
parsen, durchlaufen lassen.

von Uwe B. (boerge) Benutzerseite


Lesenswert?

... ja, so meinte ich auch ungefähr, als ich schrieb, dass diese 
Geschichte auch in jedem anderem Stack relevant wird, wenn die 
Datenpakete halt nur groß genug sind...

Uwe

von Simon K. (simon) Benutzerseite


Lesenswert?

Uwe Berger wrote:
> ... ja, so meinte ich auch ungefähr, als ich schrieb, dass diese
> Geschichte auch in jedem anderem Stack relevant wird, wenn die
> Datenpakete halt nur groß genug sind...
>
> Uwe

Gerade nochmal gelesen: Jep, du hast Recht.

Mir gefallen solche minimalistischen Stacks wie der uip auch sehr gut. 
Vorteile sind, wie schon gesagt dass alles durchschaubar ist und er 
deshalb leicht eingebunden werden kann.
Das hat natürlich den Nachteil, dass man bei den Applikationen immer 
"tricksen" muss. Je nachdem worum es genau geht.

von Dirk B. (sharandac)


Lesenswert?

@Uwe,

da haben wir wohl an einander vorbei geredet :-) Aber nix für ungut.
Simon hat soweit recht mit der größe der TCP-Packete. Die MSS bestimmt 
die maximale größe eines TCP-Packet und die wird bei uIP von der 
Puffergröße abgeleitet. Zusätzlich wird auch eine Windowssize mit TCP 
von der größe des Puffers übertragen bei uIP, damit der Sender nicht 
mehr Daten in mehreren Packeten senden kann als der Empfänger puffern 
kann kann. Somit kannst du sehr gut beeinflussen das du nicht zu viele 
Daten auf einmal bekommst.

@Simon,

Die maximale MSS wird bei Ethernet durch die maximale größe des 
Ethernetpacket begrenzt (1518 Byte minus IP- und TCP-header) und nicht 
durch IPv4. IP-Packete und damit auch TCP-Packete können bis zu 64KB 
groß sein, welche aber erst mit neuen Ethernetkarten unterstützt werden, 
da diese Jumpo-frames erst unterstützen.

von josefk (Gast)


Lesenswert?

OK. Danke für die Antworten. Da waren einige Sachen dabei, die sehr 
nützlich sind. Vor allem das mit den Statusvariablen von Simon. Das 
scheint mir auch bei mir sinnvoll zu sein, auch wenn bis jetzt noch nie 
mehr als 1,5kB Daten zum Parsen angefallen sind :)

von Jörg (Gast)


Lesenswert?

Hi,

in meinem Server übertrage ich Daten sehr unterschiedlicher Größe: ganz 
kleine (8 Byte) und ganz große (>600 kByte) "Pakete". Das Protokoll ist 
ganz einfach: immer die Größe des "Paketes" und dann die Daten 
hinterher. Das Parsen der Daten in der uip-Routine muß sowieso immer 
gemacht werden (Stichwort: Zustandsautomat), weil es kann ja immer sein, 
dass Frames fehlerhaft und nochmal übertragen werden müssen.

Nach etwas Studie der uip-Doku habe ich es halbwegs (für meine ersten 
Ziele zumindest) durchschaut.

Gruß
Jörg

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.