Forum: Mikrocontroller und Digitale Elektronik Network Essentials ;)


von Simon K. (simon) Benutzerseite


Lesenswert?

Hallo,

Wie ich sicher schon oft erwähnt habe, bin ich gerade dabei, eine NIC an 
einem AVR zum Laufen zu bringen.

Bisher funktioniert alles sehr gut. Mittlerweile bin ich dann bei der 
TCP Implementierung angekommen.

Mein Programm ist so aufgebaut, dass nach bestimmten Kriterien (zB Port, 
Protcol Type) ein bestimmter Handler aufgerufen wird.
Wird zum Beispiel ein HTTP Paket empfangen sieht das wie folgt aus:

+ IP
  +ICMP_Handler
  +TCP_Handler
    +HTTP_Handler <---
    +TCPSYN_Handler
    +FTP_Handler

+ ARP_Handler

Und schon ist das Paket am HTTP Handler angekommen, der das Paket auf 
"GET " usw überprüfen kann.

Meine TCP Implementierung ist zur Zeit aber sehr sehr einfach gehalten. 
Es werden statische Variablen für Sequence und Acknowledge Counter 
verwendet.
Nun wollte ich es aber möglich machen, dass mehrere Verbindungen 
parallel aufgebaut werden können. Dafür wollte ich dann ein 
Socket-Struct-Array erstellen, wo Ack und Seq Counter nach jedem Empfang 
gespeichert werden.
Allerdings, bevor diese gespeichert werden können, muss ich ja erstmal 
das zugehörige Socket-Struct in dem Array finden.
Nunja, wonach muss ich da jetzt suchen?

Soweit ich das verstehe wird der Empfänger, sowie der Sender Sequence 
und Acknowledge Counter im Paket vertauschen und auf den Acknowledge 
Counter die Anzahl der Payloadbytes im TCP Paket aufaddieren.

Allerdings sprengt sich mein Kopf immer in tausend Teile, wenn ich 
versuche "parallel" zu denken. Also so nach dem Motto "Was ist wenn zwei 
Clients verbindungen auf Port 80 aufbauen? Dann muss der (HTTP) Daemon 
ja unterscheiden, wem er die Pakete schickt." Aber der HTTP Daemon hat 
ja irgndwie nichts mit den Acknowledge/Sequence Countern zu tun.

Nunja, wie wird sowas bei richtigen HTTP Servern gemacht? Wird erst der 
eine "GET " bearbeitet und dann der nächste.. usw ? Wäre ja blöd, weil 
wenn ein Client eine 5GB Große datei "GET"et, dann ist der HTTP Server 
ja für Jahre nicht ansprechbar.
Kann mir da jemand irgndwie Hilfestellungen geben, Internetseiten wo 
solche "Algorithmen" mal behandelt werden.

PS: Ich habe hier nebenbei den Code von Ulrich Radigs Seite offen und 
muss echt sagen (sorry!): Da blickt doch kein Mensch durch! Ich finde 
der Code ist dermaßen kompliziert geschrieben, dass es mich wundert, 
dass es überhaupt funktioniert. Ich bin ja jetzt fast auf der 
Entwicklungsstufe von Ulrichs Webserver und ich finde mein Programm ist 
wesentlich strukturierter und logischer. Vielleicht falle ich ja auch 
damit auf die Nase, weil ich so manche Sachen nicht implementieren kann, 
aber das glaube ich eher nicht.

Naja, wie auch immer. Danke schonmal für irgndwelche Tips oder Hilfen.

von Jakob L. (jakob)


Lesenswert?

Hallo,

vielleicht ist es für deine Anwendung sinnvoller, einen fertigen TCP/IP 
Stack zu verwenden. Ich habe mit google ( suche nach embedded tcp ip 
stack ) sofort uip gefunden. Das ist ein sehr kleiner TCP/IP Stack für 
µC. Es gibt sogar schon einen Port für AVRs. Der Quellcode ist gut 
dokumentiert und es gibt fertige Beispielanwendungen (z.B. einen HTTP 
Server). Auch wenn du am Ende selbst programmieren willst, kannst du 
sicherlich einiges aus den Quelltexten anderer TCP/IP implementierungen 
lernen.

Gruss
Jakob

von Unbekannter (Gast)


Lesenswert?

Die Antworten auf Deine Fragen sind vermutlich zu umfangreich für dieses 
Forum. Ein excellentes Buch das viele Deiner Fragen beantwortet ist:

   http://www.amazon.de/Computer-Networks-Andrew-S-Tanenbaum/dp/0130384887

Ansonsten:

Du musst halt irgendwie die Prallelität implementieren. Dazu brauchst Du 
irgendeine Datenstruktur, in der Du speicherst, was Du in der 
entsprechenden Verbindung als letztes gemacht hast. Also, hast Du schon 
mit einem SYN/ACK geantwortet, ist der GET-Request schon komplett 
empfangen worden, wieviel von Deiner HTML-Seite hast Du schon 
verschickt, ist das ACK für das letzte Datenpaket mit einem Teil Deiner 
HTML-Seite schon eingetroffen usw.

Die passenden Daten-Struktur findest Du nach den Quell- und 
Ziel-IP-Adressen und -Ports.

von Sebba (Gast)


Lesenswert?

also das ganze ist eigentlich ganz einfach:
jede verbindung kannst du eindeutig an Port und IP erkennen
der Server hat immer den gleichen Port/IP insofern musst du dir nur vom 
Client den Port und die IP merken und mit in dein Struct speichern, denn 
kein Client kann 2 Verbindungen gleichzeitig über einen Port laufen 
lassen (Also kann er schon, aber nicht zum gleichen Server)

Und dann hast du deine Sequence und Acknowledge Nr. und anhand der 
kannst du bestimmen was zutun ist.

Also in etwa so:

1. Paket kommt
2. Prüfe ob Client IP/Port zu einer gültigen Verbindung gehört
   nein: Ist es ein Syn (Verbindungsaufbau) und ist noch Platz für weite
         Verbindung - Eröffne Verbindung und speichere IP/Port
   ja: Überprüfe Status: (Gibt es einige zu unterscheidende Fälle, 
gerade
       beim Verbindungsauf/abbau)

       Wenn Verbindung steht sende X Bytes beginnt ab der angekommenen 
Ack
       Nr.

(Naja, das war jetzt ziemlich unvollständig, aber ich denk mal du hast 
dich da sicherlich schon einigermaßen eingelesen)
Der springende Punkt ist eigentlich nur dass du die Parallelität 
automatisch dadurch erreichst, dass deine 5 Gig ja nicht auf einmal 
sondern in ganz vielen Paketen ~ 1500 Bytes gesendet werden - wenn jetzt 
zwischendurch ein Ack Paket von einem anderen Client ankommt wird erst 
der Client wieder mit Daten gefüttert...

Du musst dich also um die "Parallelität" nicht kümmern sondern nur immer 
das aktuelle Paket eindeutig zuordnen und beantworten

Ich hoffe das war jetzt einigermaßen transparent
Grüße, Sebba

von Simon K. (simon) Benutzerseite


Lesenswert?

Jep, ich danke euch. Habe gestern noch AVReth gefunden, der stack ist 
ziemlich gut auskommentiert. Ich denke das reicht mir schon :-)

von Dirk B. (sharandac)


Lesenswert?

Hallo,

die frage ist wie kompliziert du das machen willst. Willst du das 
mehrere verbindungen gleichzeitig offen sind und die der reihe nach vom 
http-server abgearbietet werden, oder das die verbindungen auch 
gleichzeitg von http-server verarbeitet werden. Die zweite methode ist 
ungleich kompilierter als die erste.
Ich selber habe die erste methode realisiert, der tcp/ip-stack kann 
mehrere verbindungen gleichzeitig verwalten, was der speicher halt her 
gibt. Ich habe für jede verbindung einen kleinen speicher angelegt, in 
den die daten zwischengespeichert werden in einer art ringbuffer und 
dann per socketnummer abgerufen werden können. Auf diese art und weise 
ist der http-server recht einfach zu bauen, er braucht nur nach neuen 
sockets sehen und diese bearbeiten, wobei neue verbindungen auch 
angenommen werden, aber noch nicht bearbeitet werden, weil der 
http-server ja noch mit einer alten verbindung beschäftigt ist bis er 
sie schließt und eine neue offene findet. Mann muss halt abwägen 
zwischen aufwand und nutzen.

MfG Dirk

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.