TCP IP Headerlänge grundsätzlicher Ablauf/Protokoll
-
Hallo,
ich habe mal eine grundsätzliche Frage zu TCP.
Nehmen wir zuerst das HTTP Protokoll.Wenn ich das Response vom Server erhalte steht dadrin die ContentLenght.
Ich lese also den Header fertig bis ich zur Leerzeile mit <CR><LF> komme.
Dann lese ich die ContentLenght ein.Was tut man wenn man die ContentLenght nicht komplett vom Server bekommt? Timeout?
Ich muss eine Kommunikation zu einem übergeordneten PC herstellen über ein spezielles Protokoll.
Hier ist die Headerlänge fix mit 3 Byte. Im Header steht die Message ID und die Länge der Daten. Wie soll ich hier erkennen ob ich den Header komplett empfangen habe? (Bisher habe ich immer eine bestimmte länge eingelesen und somit das ganze Telegramm in den Buffer geholt, aber hier geht es mir jetzt um die andere Methode).
Wenn ich die 3 Byte Header erhalten habe, könnte ich die durch den Header definierte Länge, Telegrammdaten einlesen und diese Parsen. Was aber tun, wenn ein Fehler auftritt, z.B. wenn nicht alle Daten gesendet werden oder zu viele Daten gesendet werden, dann währe der nächste Header falsch.Vielen Dank an alle die sich diesem Problem annehmen!
-
Anaconda55 schrieb:
Was tut man wenn man die ContentLenght nicht komplett vom Server bekommt? Timeout?
Es gibt 2 moegliche Loesungen:
- ewig warten (sprich solange bis der Server die Verbindung beendet)
- selber nach einer gewissen Zeit die Verbindung beenden
Prinzipiell ist dann aber ein Fehler aufgetreten. Je nach Daten die man ausgetauscht hat ist ein wegwerfen der Daten und Anfrage neu schicken sinnvoll.
Hier ist die Headerlänge fix mit 3 Byte. Im Header steht die Message ID und die Länge der Daten. Wie soll ich hier erkennen ob ich den Header komplett empfangen habe?
Sobald du 3 Bytes hast, ist der Header komplett.
Es kann nicht passieren dass ein Byte bei der Uebertragung verloren geht.Wenn ich die 3 Byte Header erhalten habe, könnte ich die durch den Header definierte Länge, Telegrammdaten einlesen und diese Parsen. Was aber tun, wenn ein Fehler auftritt, z.B. wenn nicht alle Daten gesendet werden oder zu viele Daten gesendet werden, dann währe der nächste Header falsch.
Dann ist ein Fehler aufgetreten und die Kommunikation muss neu initialisiert werden.
Wenn die Pakete direkt hintereinander bei dir eintreffen, musst du ihnen vertrauen, dass die Laenge passt. Ansonsten verwendet man oefters auch ein Start Zeichen und ein End Zeichen. Bei HTTP ist es zB so, dass der Server dir nur ein Paket schickt. Dann musst du selber wieder aktiv das naechste Anfragen.
-
Dann ist ein Fehler aufgetreten und die Kommunikation muss neu initialisiert werden.
Wie könnte dann so eine neu Initialsierung aussehen? Der Server trennt die Verbindung zum Client?
-
Anaconda55 schrieb:
Dann ist ein Fehler aufgetreten und die Kommunikation muss neu initialisiert werden.
Wie könnte dann so eine neu Initialsierung aussehen? Der Server trennt die Verbindung zum Client?
Der Client trennt. Der Server weiss ja uU nichts davon. Aber im Prinzip kann auch der Server trennen. Je nachdem wie das Protokoll aussieht passiert dann eben "etwas".
Bei HTTP ist es idR so, dass nichts passiert und der Client ewig wartet und eben das anzeigt was er bekommen hat. Was zB zu korrupten Downloads führen kann. aber bei HTML Seiten kann es sein dass der Fehler ja nichtmal auffällt.
Prinzipiell muss das Protokoll natürlich definieren was in einem Fehlerfall passieren soll. HTTP ist easy. Es ist stateless, was bedeutet: der Client fragt an, der Server antwortet - fertig aus ende. Es gibt keine weitere Kommunikation. Jede neue Anfrage des Clients ist komplett unabhängig von vorhergehenden.
PS:
bei TCP ist es anders. Dort muss jedes Paket bestätigt werden und die bestätigung muss ebenfalls bestätigt werden. Sonst wird das Paket neu gesendet.
-
OK.
Aber es wäre sinvoll, das der Teilnehmer, den der Fehler auffällt trennt.
Sollte man dann bei einem Header von 3 Byte , 3 Byte einlesen, wenn man aber nur 2 Byte empfängt auf das 1 Byte noch warten und dann die länge des Telegramm definiert durch den empfangenen Header erwarten, wenn hier nicht die Länge ankommt wieder warten, bis die Länge ereicht ist, dann parsen usw ...Wäre das sinvoll oder soll man gleich die komplette erwartete Länge empfangen und wenn diese Länge nicht übereinstimmt kommt es zum Fehler?
-
Anaconda55 schrieb:
Aber es wäre sinvoll, das der Teilnehmer, den der Fehler auffällt trennt.
Ja. Denn wenn du einen Fehler bemerkst, bedeutet das ja, dass irgendetwas schief gegangen ist. Du weisst aber nicht was. uU sind alle Daten die du bekommst korrupt. Du weisst es nicht. Deshalb ist meistens die einfachste Lösung: alles wegschmeissen und neu anfangen.
Sollte man dann bei einem Header von 3 Byte , 3 Byte einlesen, wenn man aber nur 2 Byte empfängt auf das 1 Byte noch warten und dann die länge des Telegramm definiert durch den empfangenen Header erwarten, wenn hier nicht die Länge ankommt wieder warten, bis die Länge ereicht ist, dann parsen usw ...
Prinzipiell ist es so, dass 3 Byte locker in ein TCP Paket passen. Das bedeutet dass sie immer gleichzeitig ankommen werden (in der Praxis zumindest). Du kannst also einen sehr sehr sehr kurzen Timeout verwenden innerhalb dessen die 3 Bytes ankommen müssen.
Wäre das sinvoll oder soll man gleich die komplette erwartete Länge empfangen und wenn diese Länge nicht übereinstimmt kommt es zum Fehler?
Zuerst den Header lesen. Das musst du ja sowieso, sonst weisst du nicht wieviele Daten kommen werden.
Aber ich glaube wir reden hier viel zu abstrakt. Kannst du vielleicht etwas konkreter werden und deine aktuelle Situation etwas genauer beschreiben.
Wichtig bei einem Protokoll ist auch ob es stateful oder stateless ist. HTTP ist zB stateless, was es ziemlich trivial macht mit Fehlern umzugehen. TCP ist statefull, hier sind Fehler schon komplizierter zu handhaben.
-
Aber ich glaube wir reden hier viel zu abstrakt. Kannst du vielleicht etwas konkreter werden und deine aktuelle Situation etwas genauer beschreiben.
Wichtig bei einem Protokoll ist auch ob es stateful oder stateless ist. HTTP ist zB stateless, was es ziemlich trivial macht mit Fehlern umzugehen. TCP ist statefull, hier sind Fehler schon komplizierter zu handhaben.
Ich habe 4 verschiedene Telegramme.
MID 1,2,3,4
Jedes hat eine bestimmte Länge.Ich würde sagen es ist statefull.
Ablauf ist folgender:
MID4 Empfangen
MID1 Senden
MID2 Empfangen
MID3 Senden
MID4 Empfangen
usw...