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....
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.
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 :)
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
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
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
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.
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.
... 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
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.
@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.
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 :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.