INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.


Antwort schreiben 

TCP IP Kommunikation - Philosophie



Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!

01.08.2011, 16:31 (Dieser Beitrag wurde zuletzt bearbeitet: 01.08.2011 21:31 von jg.)
Beitrag #1

Kiesch Offline
LVF-Stammgast
***


Beiträge: 412
Registriert seit: Mar 2009

2019, 2018, 2016
2009
DE

04519
Deutschland
TCP IP Kommunikation - Philosophie
Hallo liebe LVF Nutzer,

ich habe eine TCP / IP Kommunikation realisiert, bei der ein VI als Sender / Empfänger fungiert das die zu sendenden Daten per Queue erhält und auch per Queue ausgibt was es empfängt. Für Senden und Empfangen wird jeweils eine TCP Verbindung geöffnet. Über eine INI kann ich IP; Ports und die Namen der zu benutzenden Queues in das Programm geben, so dass ich das einfach auf beiden zu verbindenden Rechnern ablege und dann einfach ausführen muss.
An sich funktioniert das aktuell auch ganz gut, allerdings ist mir ein Problem mit meiner Übertragungsphilosophie aufgefallen:

Variante A)
Aktuell besteht ein Sende / Empfangsbefehl immer aus 2 TCPwrite / read Befehlen. Erst wird ein 4 Byte Wert übertragen der die Anzahl der nachfolgenden Byte angibt, danach wird entsprechend viel gelesen.
Soweit so gut. Funktioniert auch meistens ganz gut. Das einzige Problem ist, dass ich schonmal gesehen habe wie er beim testen aus dem Takt geraten ist und dann garnichts mehr ging (da mir keine einfache Möglichkeit einfällt den wieder auf den korrekten Startwert zurückzustellen (die 4Byte für die Länge der nachfolgenden Daten).
Leider muss das ganze aber irgendwann mal stabil zum Beispiel nen Tag lang laufen da ich damit nen Steuer- und nen Messrechner miteinander kommunizieren lasse. Hat jemand da nen Ansatz dafür wie man das mit nicht zu viel Aufwand entsprechend anpassen kann?


Variante B)
Alternativ könnte man das ganze natürlich auch so umbauen, dass immer auf die nächsten 1kByte gewartet wird. Entsprechend müssten dann die Datenpakete mit einem Identifier anfangen ("###" zum Beispiel; im Prinzip muss das ja lediglich was unübliches für Strings sein, da an sich jede Zeichenkombination auch mit einer gewissen Wahrscheinlichkeit in einem willkürlichen Datensatz vorkommt).
Anschließend die Zeichenzahl und Datenpakete die nicht 1024Byte haben müssen mit 0en aufgefüllt werden (es soll möglichst schnell versendet werden; da das ganze in nem 100MBit LAN sitzt denke ich kann man den Overhead im Prinzip in kauf nehmen; alternativ könnte man natürlich auch mehrere Datenpakete auflaufen lassen (über 5 / 10 ms sammeln wenn nicht vorher 1024Byte voll werden) und anschließend erst versenden, nur dazu muss man dann auch den Header am anfang erweitern damit die Datenpakete wieder sauber aufgeschlüsselt werden können - die Datenpakete in meinem Fall aus einem Befehl und Daten den dann die Programme auf den jeweiligen PCs weiterverarbeiten - entsprechend ist es wichtig, dass die Pakete wie in der Queue auch als einzelne Pakete ankommen und nicht wie über die TCP IP Verbindung als Bytestream).
Der Vorteil dieser Variante ist, dass sie selbstrückstellend sein sollte. Man kann relativ leicht prüfen ob am Anfang des gelesenen Inhalts "###" steht und wenn nicht danach in den restlichen Daten suchen und dann entsprechend ab dieser Position weiterlesen bis die 1024Byte voll sind. Damit hat man dann vermutlich einmal Unsinn verarbeitet und die zweite Hälfte der übertragenen Daten verloren, aber anschließend sollte man in den meisten Fällen wieder normal weitersenden können. (der String "###" dürfte hinreichend eindeutig sein um nicht allzuoft zufällig aufzutreten; in den meisten Fällen, zum Beispiel wenn ich Strings versende sollte der sogar ausgeschlossen sein). Versieht man das ganze mit einer ID für jeden Sendevorgang kann der Empfänger sogar jeweils den Empfang quittieren. Dann könnte man sogar sicher verlustfrei versenden (nichtbestätigte Sendungen werden einfach wiederholt).


Nur macht der ganze Aufwand auch Sinn? Sprich, habe ich irgendeine einfache Variante übersehen die bei "Länge und Daten versenden" eine ähnliche Rückstellung bewerkstelligt? Ich hatte das ganze versucht indem ich bei Timeout während dem Lesen (was typischweise passieren sollte wenn dabei was schiefgeht und dann eben auf weitere Daten gewartet wird) die Verbindung schließe und neu Aufbaue, aber scheinbar war das nicht ausreichend oder hat aus anderen Gründen nicht geklappt. (kann natürlich nicht ausschließen dass meine Timings für Timeout und neu Verbinden etc. so blöd gewählt waren das das prinzipiell nicht funktionieren konnte). Und sollte man vielleicht generell nach Variante B verfahren, da die nunmal zwar aufwändiger aber eben auch "automatisch" selbstrückstellend ist (?).

Zitat:Märchen und Geschichten werden erzählt am Lagerfeuer, technischen Fakten werden mitgeteilt (oder so). (Genauso wie Software nicht auf einem Server "herumliegt", die ist dort installiert.)
*Zitat: IchSelbst*
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
01.08.2011, 17:12 (Dieser Beitrag wurde zuletzt bearbeitet: 01.08.2011 17:18 von macmarvin.)
Beitrag #2

macmarvin Offline
CLA
***


Beiträge: 445
Registriert seit: Sep 2006

2014
2004
EN

81373
Deutschland
RE: TCP IP Kommunikation - philosophie
Ich würde Variante A leicht abgewandelt empfehlen.

Nur 1 TCP Verbindung, 4 Byte als Nachrichtenlänge sind gut, 1 mal anstatt 2 mal TCP Write (also den String vorher zusammen bauen), 2 mal TCP Read (Länge dann Nachricht) wie gehabt.
Sowas in der Art läuft eigentlich schon sehr stabil, eine Reconnect Logik wäre für einen Dauerläufer sicher sinnvoll.

Edit:
Was ich schonmal gesehen habe als Fehlerquelle:
Den I32 der Länge unbedingt per Typecast und nicht per "Number to Decimal String" in einen String wandeln, sonst ist geht's bei Nachrichtenlänge >9999 schief (siehe auch Simple Data Server/Client Example).
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
02.08.2011, 10:11
Beitrag #3

Kiesch Offline
LVF-Stammgast
***


Beiträge: 412
Registriert seit: Mar 2009

2019, 2018, 2016
2009
DE

04519
Deutschland
RE: TCP IP Kommunikation - Philosophie
Hab das mit Daten serialisieren / deserialisieren gemacht - also das ist scheinbar nicht das Problem. (obwohl er mir damals tatsächlich offenbar mitten bei der Übermittlung eines längeren Arrays abgekackt ist.

Zur Verwendung einer Verbindung:
Die Bytestreams an sich dürften ja zwar getrennt sein (sprich: Ich kann nur lesen was der andere Rechner schreibt - richtig?), aber eigentlich wollte ich auch beiden Rechnern die Möglichkeit geben "aktiv" einen Verbindungsaufbau zu versuchen.
Hatte außerdem das Gefühl, dass ich das so logisch auch besser voneinander trennen kann.


P.S: sollte Number to string nicht auch bei <1000 schiefgehen? dann sinds ja nur noch 3 Zeichen also wird das erste Zeichen vom Datenstring noch mit zur Nummer dazugelesen. Das sollte eher wenig witzige Ergebnisse produzieren.

Zitat:Märchen und Geschichten werden erzählt am Lagerfeuer, technischen Fakten werden mitgeteilt (oder so). (Genauso wie Software nicht auf einem Server "herumliegt", die ist dort installiert.)
*Zitat: IchSelbst*
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
30
Antwort schreiben 


Gehe zu: