Hallo, aus den Bedürfnissen des Ulrich Radig Webserver Threads (http://www.mikrocontroller.net/forum/read-4-87092.html#157645) entstanden, gibt es nun diesen Thread zur Diskussion von tiefgründigerem Netzwerkwissen. Als Projekt zu einer Vorlesung habe ich mit 3 Kommilitonen einen relativ vollständigen TCP/UDP/IP Stack implementiert, inklusive GET Parser für HTTP Requests und DHCP Client. Angefangen hat das ganze bei Ulrichs Webserver, inzwischen ist aber nur noch die unterste Schicht davon übrig ;-) Das Wiki zum Projekt ist grad im Umzug begriffen, aber in den nächsten Tagen werde ich das ganze inklusive Source hier posten, so dass alle etwas davon haben. Bis dahin können wir ja gern hier weitere Fragen zu TCP/IP und Co. klären :-) Gruß, Jon
:
Hi Jon, das mit dem DHCP-Client würde mich auch interessieren. Sicher ist es diskussionswürdig bei einem kleinen AVR-System mit dynamischer IP-Vergabe zu arbeiten aber allein das Prinzip zu verstehen ist ja schon interessant. Wie schon im erwähnten Thread angesprochen ist mir eben aufgefallen, dass in den verschiedenen TCP/IP-Implementationen, die so im Netz rumgeistern, teilweise gravierende Abweichungen auftreten. Vor allem beim Socket-Status. Laut RFC793 (dem TCP/IP-Spezifikation http://www.faqs.org/rfcs/rfc793.html) durchläuft eine TCP/IP-Verbindung die Stadien: CLOSED ----------------------------------------------------------------- LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, ----------------------------------------------------------------- {Datenaustausch} ----------------------------------------------------------------- FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT, ----------------------------------------------------------------- CLOSED So habe ich das allerdings nirgendwo implementiert gesehen. Die Frage ist eben nun, ob man sich die Mühe machen sollte das zu tun oder nicht . Gruß Andreas
Für kleine Controller würde natürlich auch RARP reichen, oder halt BOOTP. DHCP ist in der Tat eine Nummer zu gross. Gibt es eigentlich schon irgendwo eine Netzwerkdateisystemimplementierung, z.B. NFS? Als Client und/oder als Server?
@Hebel Wir haben die Connection Status genau so implementiert. Lediglich die Statusnummern könnten abweichen, aber wie schon erläutert macht das ja nicht. Achja: Den Status Closed gibt es bei uns auch nicht, weil die Connections sofort wieder in den Listen Status wechselt. Ach ja, ein Socket kann durchaus an mehreren Verbindungen mit unterschiedlichen Status teilnehmen, die Formulierung "Socket Status" ist also eigentlich etwas unglücklich. @Andreas Naja.. DHCP nutzt ja Bootp als Protokoll. Natürlich implementieren wir nicht alle Optionen von DHCP, aber das ist ja auch nicht nötig. Wir haben das so auf einem ATmega32 am Laufen. An NFS habe ich auch schon gedacht, würde mich brennend interessieren wie aufwendig das ist. ps. Zweimal Andreas? ;-)
Und noch ein Andreas ;-) Unser CVS-Server ist leider nicht oeffentlich deswegen hier ein Source-Tarball vom CVS gezogen. Eine Wiki-site ist schon da aber momentan noch offline, kurze Erlaeuterungen deswegen hier: - Die Software ist noch ziemlich Alpha und im Moment wenig mehr als ein Proof-of-Concept - Das ganze wurde geschrieben fuer einen ATmega32 und eine RTL8019AS ISA-Karte. Die oberen Schichten (arp/ip und aufwaerts) sind einigermassen portabel, die unteren nicht. Auch im Makefile sind Anpassungen noetig fuer das jeweilige Setup. - Ethernet: Nicht jedes Ethernet Paket wird korrekt hochgereicht. Wir wissen nicht genau, woran es liegt. - ARP: Die Cache ist noch nicht intensiv getestet, da wir einfach zu wenig Platz hatten, um sie groesser zu machen. - IP: Der ARP-Check von IP_SEND ist nicht ideal, funkioniert aber. Leider streikt hier die globale Clock, deswegen sind Retransmitts nicht timetriggered. - TCP: arbeitet nicht vollständig korrekt mit manchen Browsern. Retransmitts wie IP. Es gibt noch mehr, aber das sind die wichtigsten. Also wer mutig ist, der ziehe seine Gummistiefel an und ab in den Sandkasten :-)
@Andreas#4 ;-) Keine Ahnung, wir haben beide nicht angeschaut. Unser Ziel ist die vollständige Implementation von IP, TCP, UDP den entsprechenden RFCs entsprechend. Das ist vor allem ein Studienprojekt, um es selbst zu verstehen. Wenn man so einen Stack mal selbst implementiert hat, kennt man viele der Probleme und kann die Erfahrung für andere Entwicklungen nutzen. Sollten die von Dir genannten Stacks das bereits voll unterstützen, so ist unsere Arbeit höchstens eine weitere in diese Richtung.
Hallo, Da muß ich Jon schon recht geben man muß einen TCP/IP-Stack schon selbst programmieren um TCP/IP zu verstehen. Es gibt einige Projekte in diese Richtung. Mfg Ulrich
Auch ich möchte dem beipflichten. Auch ich bin einer derjenigen, die TCP/IP auf nem Mega128 implemtiere! Und ebenso läuft bei mir das Ganze unter dem Kontext "Erfahrungssammlung" und "Wissen wollen wie das funktioniert". mfg Andreas
zu meinem vorigen Post noch eine kurze Ergänzung: Vorallem würde mich interessieren, wie ihr das "Demultiplexing" der Ethernet Frames handhabt. Bei mir läuft das momentan so, dass eine Art "Scheduler" die Frames den entsprechenden Funktionen übergibt. Beim Vorbereiten der Frames zum Senden soll ja jede Schicht ihren Header hinzufügen. Nur ist das teilweise nicht so einfach, da ja z.B. IP sehr viele Informationen einfügen muss, die ich nicht unbedingt übergeben will. Und wenn ich zuvor eine Struktur füllen muss, dann kann ich es gleich in den Header auch schreiben... wäre da mal sehr an einem Erfahrungsaustausch interessiert! Die andere Frage, die ich noch habe, betrifft zwar nicht direkt TCP/IP, könnte aber als in diesem Zusammenhang ganz interessant sein! Und zwar hätte ich eigentlich vor, ein kleines Multithreading zu realisieren. Und zwar so, dass z.B. HTTP, FTP und ähnliche Server als eigene Threads laufen. Jetzt ist eben die Frage, ob das schonmal jemand versucht hat (also z.B. "_einfaches_" kooperatives Multithreading) zu realisieren. Von der Performance her sollte es ja doch ein bisschen was bringen, oder?? Begründung: oftmals kommt man ja in die Lage, dass man im Laufe eines Programms (Servers) auf etwas warten muss (Benutzereingaben u.ä.)... und währenddessen kann man ja die Rechenleistung für einen anderen Thread nutzen! mfg Andreas
Naja gehen musses, ethernut macht es ja genauso (glaub ich :) http://www.ethernut.de/de/software.html
Nochmal kurz ein kleiner Beitrag (der etwas Offtopic ist sorry): Es wäre ja ganz nützlich in der Library (bzw. als Erweiterungslibrary) des avr-gcc einfache Funktionen für einfaches Multithreading bereitstellen zu können! Vielleicht könnte man ja ein Gemeinschaftsprojekt auf die Beine stellen und sowas entwickeln. Meine Vorstellung ging da in die Richtung: void createThread(void *function,...); mfg Andreas
Ein kooperatives Multitasking lässt sich ziemlich einfach mit setjmp/longjmp realisieren. Ich habe sowas mal für ARM geschrieben, mal schaun ob ich den Sourcecode noch finde.
Ist im Anhang. Nur wenig getestet, hat aber soweit ganz gut funktioniert wenn ich mich recht erinnere. Näheres zu dem Thema sollte man in Google finden.
@Andreas Aur Zum Demultiplexing: Schau einfach mal in die Source, die AndreasD gepostet hat :-) Prinzipiell haben wir einen großen Puffer in dem das Paket landet. Jede Schicht ist dafür zuständig ihren Teil zu interpretieren. Die Header werden meistens angesprochen, indem ein StructPointer auf die entsprechede Stelle im Paketpuffer zeigt. So verschwendet man lediglich den Platz für den Pointer (2Byte), hat aber bedeutend mehr Komfort.
@Andreas Aur Grundsaetzlich, die Source erklaerts am besten. Also, einen Scheduler in der Art haben wir nicht. Ein Paket loest einen Interrupt aus, daraufhin wird der Ethernet-Header ausgelesen, geparsed und entsprechend an arp oder ip weitergeleitet, die gucken ob ihr Puffer gerade blockiert ist, wenn nicht wird weiter ausgelesen und in den eigenen Puffer geschrieben. So geht das dann die Schichten hoch. Der Puffer ist ein globales vordefiniertes Byte-Array (siehe mem.h). Jede Schicht passt aber selber nur auf ihren Bereich darin auf. Uebergeben werden beim senden dann Pointer auf die zu sendenden Bytes. Die Header und Payload komplett zu uebergeben ueberfuellt dir den Stack und ich finde es mit Pointern auch wesentlich eleganter. Zum Multithreading: Sehr interessant. Ich denke aber auf unserem atmega32 ohne extra ram ist es nicht zu realisieren. Das stapelt dir ja auf den Stack wie nix gutes ;-)
[X] per Email über Antworten auf diesen Beitrag informieren
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.