TIA Verhalten TSEND/TRECV bei großer Blocklänge

Ingmar64

Level-2
Beiträge
339
Reaktionspunkte
57
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich stehe vor der Aufgabe, zwischen je 2 S7 SPS (teils 1500-<>1500, teils 1500<->300PN) ca. 4kB (konst. Länge) Daten auszutauschen. Die prinzipielle Konfiguration und Programmierung ist mir klar, mir geht es aber um folgende Frage: Wie verhält sich TRECV bei Verbindungsproblemen? Ich kann zwar an beiden Seiten (TSEND u. TRECV) die zu übertragende Datenlänge angeben, aber kann ich auch sicher sein sein, daß ich auch wirklich auf der Empfangsseite einen korrekten zusammenhängenden Block erhalte und nicht 2 Teile von zwei verschiedenen Paketen, die eben gerade die richtige Länge haben. Welchen Aufwand muß ich treiben, um das abzusichern?
Ich frage aus der Erfahrung, daß bei Konfigurationen mit variabler Länge (z.B. Meßergebnisse von einem Sensor) durchaus auch schon ohne Netzwerkstörungen mehrere (Teil-)Pakete in einem Rutsch erhalte und ich nach Anfangs- und Endesequenzen suchen und portionieren/verwerfen muß.
Oder gibt es alternative sinnvollere Wege?

Danke!

PS: Ich kenne die Standardbeispiele von Siemens dazu, auch das große Kommunikationskompendium. Aber diese Frage scheint mir dort nicht ausreichend beantwortet.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bei TCP gibt es keine Blöcke, es ist ein Datenstrom.

Wenn du auf der einen Seite z.B. direkt nacheinander per Send 4 kByte große Daten absendest, dann ist gesichert dass dieses Daten auch in der abgesendeten Reihenfolge beim Empfänger ankommen.
Aber kommen nicht im Block an, sondern z.B. werden beim ersten Receive 1000 Bytes, dann 1400, dann 1000 usw. gelesen. Wenn die Verbindung dann unterbrochen sein sollte, dann hast du eben nur 3400 Bytes in deinem Empfangspuffer, und genau das muss deine Anwendung abfangen D.h. sie erwartet 4096 Bytes, und wenn diese Anzahl nicht empfangen wurde dann weißt du, dass dieser Datensatz nicht komplett ist.

Darum kannst du entweder auf beiden Seiten immer mit festen Datenlängen arbeiten, oder du sendest den Daten eine Längenangabe vorweg, sodass der Partner nach den ersten paar Bytes weiß wie viele Daten er noch zu lesen hat.
Das einzig "schwierige" an TCP ist mit diesem Verhalten korrekt umzugehen, z.B. Sender und Empfänger nach einer Störung wieder synchron zu bekommen. D.h. der Empfänger muss dann seine ggf. teilweise empfangenen Blöcke verwerfen und bei Null beginnen. Andernfalls hast du auch bei festen Blocklängen einen Versatz in den Datenbytes.
 
@DOD666
Danke für den Tipp, die Beschreibung klingt vielversprechend nach dem, was ich gesucht habe.

@Thomas_v2.1
Genau dieses "wieder synchron" bekommen hatte ich schon als nicht so ganz einfach erfahren. Da ging es aber nur um 8-50Bytes (String) mit ziemlich eindeutigen Start- und Stopzeichen. Jetzt habe ich Arrays, die ich dann erstmal eindeutig "verpacken" müsste.
Danke für die eindeutige Antwort.
 
Mit einer festen Blockgröße ist das noch recht einfach.
Auf der Senderseite ist dabei auch nicht viel zu beachten. Der Sender schickt seine z.B. 4096 Bytes über Send ab.
Der Empfänger liest nun solange in einen internen Puffer bis er die 4096 Bytes voll hat.
Wenn noch mehr Bytes gelesen werden können, dann ist das schon ein Teil von einem nächsten Block. Das muss dann aufgetrennt werden, bzw. kannst du beim receive auch angeben wie viele Bytes du maximal lesen willst.
Hast du nun einen Teil von den 4096 Bytes gelesen und dann bekommst du beim Receive einen Fehler wie Timeout wegen Verbindungsaubbau, dann musst du die bisherigen Daten verwerfen und bei Null beginnen.

Du könntest zur Sicherheit auch bei deiner festen Blockgröße den Sendedaten ein paar feste Bytes wie 0xABADBABE voranstellen, und wenn bei deiner Auswertung diese nicht zu Beginn vorhanden sind, die Verbindung neu aufbauen um sich wieder zu synchronisieren.
Das ist aber eigentlich überflüssig wenn sich beide Partner an die Abmachung der Blockgröße halten. Aber mal angenommen der eine Partner würde nur ein Telegramm mit anstatt 4096 Bytes z.B. nur 4095 oder 4097 Bytes schicken, dann ist für die ganze weitere Kommunikation auf der Verbindung die Datenübertragung gestört, bzw. hast du dann einen Versatz in den Daten den du mangels Anfang/Endekennung oder Längenangabe weder korrigieren noch erkennen kannst.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Auf die Idee mit Verbindung ab- und wieder aufbauen bin ich noch nicht gekommen. Ich hatte bisher bei variabler Datenlänge dann immer solange alles empfangene verworfen bis meine Startkennung wieder an der richtigen Stelle war und ab da die Endekennung gesucht.
Wenn ich Dich richtig verstehe, muß ich also auf jeden Fall eine Art Handshake einbauen, daß der nächste Block erst gesendet wird, wenn der vorherige empfangen (oder verworfen) wurde, damit der nächste Empfangsvorgang auf jeden Fall mit dem Blockbeginn startet.
Ich werde mir jetzt mal die Lcom-Bibliothek anschauen, vielleicht ist da ja schon alles drin, was ich brauche. Ansonsten muß ich es eben doch selber bauen.
 
Auf die Idee mit Verbindung ab- und wieder aufbauen bin ich noch nicht gekommen. Ich hatte bisher bei variabler Datenlänge dann immer solange alles empfangene verworfen bis meine Startkennung wieder an der richtigen Stelle war und ab da die Endekennung gesucht.
Wenn ich Dich richtig verstehe, muß ich also auf jeden Fall eine Art Handshake einbauen, daß der nächste Block erst gesendet wird, wenn der vorherige empfangen (oder verworfen) wurde, damit der nächste Empfangsvorgang auf jeden Fall mit dem Blockbeginn startet.
Musst du nicht. Wenn du eine feste Blocklänge vereinbarst, dann ist das sozusagen deine Protokollvereinbarung an die sich beide zu halten haben.
In der SPS hat man es ja gerne recht einfach, da will man auch nicht unbedingt zyklisch große Datensätze nach Kennungen durchsuchen, Daten umkopieren, zusammensetzen usw.
Ich werde mir jetzt mal die Lcom-Bibliothek anschauen, vielleicht ist da ja schon alles drin, was ich brauche. Ansonsten muß ich es eben doch selber bauen.
Du könntest auch ISO-On-TCP verwenden wenn dein Partner das kann. Das ist ein blockorientiertes Protokoll (ISO) auf dem streamorientierten TCP.
Die S7 hat das schon integriert.
 
Und bei ISO-On-Tcp ist ein Versatz bei konstanter, fest eingestellter Datenlänge ausgeschlossen? Wenn ich die Beschreibung zu TRECV richtig verstanden habe, muß dort einen Puffer angeben, der größer als meine Empfangslänge ist. Und der Parameter LEN gibt mir die aktuelle Länge an. Ist es dann so, daß NDR erst reagiert, wenn der vollständige Block da ist? Wird die Datenlänge vom Sender mit übertragen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bei ISO-On-TCP wird die Datenlänge mit übertragen, ja. Davon siehst du aber als Anwender im Detail alles nichts, das ist eine weitere Protokollebene die alles für dich abnimmt.
Entweder Block vollständig und korrekt gelesen, oder eben nicht. Auswerten was in diesem Block drinsteckt, ob die Größe passt usw. musst du natürlich trotzdem selber. Nur dann hast du das Problem mit dem Zusammensetzen des TCP Streams schon mal vom Tisch.
 
Zurück
Oben