Guten Tag
Wie schaffe ich es mit dem Socket zu prüfen ob der Client/Server noch online ist ?
Meine Momentane lösung ist, dass ich nullbytes schicke und bei einer Exception weiss, dass der Server/Client nicht mehr online ist.
Das funktioniert zwar aber verursacht das Problem, das die nullbytes in den Datenstrom schleichen und somit die eigentlich gesendeten Daten verfälscht.
Momentan löse ich dieses Problem, indem ich einfach den Buffer durchegehe und die nullbytes lösche. Wenn ich aber später Binär Daten sende könnte das zu Problemen führen, da diese ja auch nullbytes enthalten können, DIE ich aber dann lösche wegen den Ping nullbytes.
Gibt es da nicht eine elegantere Lösung ?
Danke
Hallo,
hast Du untersciedliche Threads, die Dir gleichzeitig Daten auf die Leitung setzen? Es dürfte sehr schwer sein - gerade im Zusammenhang mit Binärdaten - das auf dem Client vernünftig auseinanderzuhalten.
Besser wäre, gar keine Statusabfrage zu machen solange eine Datenübertragung an den entsprechenden Client läuft (denn solange kannst Du ja sicher davon ausgehen , daß die Gegenstelle gerade online ist.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Naja eigentlich habe ich 2 Thread die Daten auf die Leitung legen.
Einmal der "Pinger" und einmal der richtige Sender.
Das ich während des normalen sendeverlaufs keine Pings schicke ist zwar gut, ich muss aber anfangs trotzdem ein paar nullbyter in der Leitung rauslöschen, da ja solange keine Daten gesendet werden, trotzdem Pings geschickt werden.
Hallo,
In Socket buffer addieren und prüfen ob alle Daten vorhanden sind. schreibst Du ja
Ich habe ein Protokoll mit Volgendermaßener "Syntax"
[Kommando][Länge der Nachricht][Eigentliche Nachricht/Datei]
Kommando = 1 byte
Länge der Nachricht = 4bytes
Nachricht = Variable
Du könntest als einfache Lösung Dein Protokoll so gestalten, daß es nie mit einem Nullbyte anfangen kann.
Dann liest Du auf dem Client solnge genau ein byte bis eines kommt, das nicht mehr null ist: Hier beginnt Dein Paket, und Du kannst schonmal das Kommando ermitteln. Die nullbytes vorher kannst Du einfach verwerfen.
Dann liest Du die Nachricht - wobei Du vorher noch durch lesen von genau 4 bytes die Länge ermitteln könntest, sonst musst Du die ja später wieder rausnehmen - und wenn deren gesamt Länge erreicht ist, fängst Du wieder an, einzelne bytes zu lesen usw.
Audf der Gegenseite sollte immer nur ein schreibender Thread laufen, damit die Daten nicht vermischt werden können.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Da war doch irgendwas dass wenn man ein leeres Array (also praktisch nichts) schickt, dass dann eine Exception kommt, falls der Socket weg ist. Ich weiß aber nichts genaues mehr darüber, vielleicht findest du ja Infos dazu.
Hallo chilic,
ich denke Dasart schickt jeweils ein inzelnes byte mit dem Wert 0
. Sonst würde sich die Frage in dieser Weise nicht stellen.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Ja schon, aber die Frage hört sich an als wollte er davon wegkommen und einen anderen Weg finden, bei dem man nichts schicken muss.
Hallo chilic,
da hab ich wohl auf dem Schlauch gesessen 🤔
Wenn das klappt, ist es sicherlich allem anderen vorzuziehen. In der Doku zu Socket.Send habe ich allerdings nichts darüber gefunden 🙁
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Jap das ist das Problem in der Doku von Socket steht sowas nicht drin, ich nehme also auch an, dass es anders nicht zu bewerkstelligen ist.
Aber das tut nämlich nicht mehr zur Sache, ich habe es so gelöst :
Sobald Daten gesendet werden steht der "Pinger" still.
Um dann noch zu vermeiden, dass noch während des Empfanges der Daten null bytes gesendet werden, wird erst wieder gepingt, wenn alle Daten wirklich angekommen sind.
Also
Daten verden gesendet Pinger wird stillgelegt.
Daten werden empfangen und beim erfolgreichen empfangen wird ein nullbyte zurückgesendet, damit klar wird, dass wirklich alle daten jetzt drüben sind.
Empfängt der Client jetzt dieses nullbyte weiß er das alle Daten erfolgreich gesendet wurden und fängt wieder an alle 10 sekunden zu pingen.
Wie schaffe ich es mit dem Socket zu prüfen ob der Client/Server noch online ist ?
Gibt es da nicht eine elegantere Lösung ?
Ja es gibt eine Lösung.
Such mal nach Socket.Poll in Verbindung mit Socket.Available
Ist ziemlich schräg aber funzt.
Wird irgend so was sein:
if (Socket.Poll(0, SelectMode.SelectRead))
{
//Socket can be read
//1) if we have Data --> Connected
//2) no Data --> not connected
//Important: we need to check again if there are bytes on the socket (we might got new data since last call to .Available !!)
isConnected =Socket.Available > 0;
}
else
{
//Socket not readable --> connected
isConnected = true;
}
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Hallo Programmierhans,
ich denke nicht daß man mit Poll
und Available
auskommt, denn
Mit dieser Methode können bestimmte Arten von Verbindungsproblemen, z. B. ein unterbrochenes Netzwerkkkabel oder das nicht ordnungsgemäße Herunterfahren des Remotehosts, nicht erkannt werden. Sie müssen versuchen, Daten zu senden oder zu empfangen, um diese Arten von Fehlern zu erkennen.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
@MarsStein
Können wir uns darauf einigen, dass mit meiner "Lösung" ein grosser Teil der Unterbrüche sehr schnell erkannt wird.
Wenn der Unterbruch allerdings irgendwo stattfindet (z.B: wenn die Verbindung geroutet wird), dann wird dies ev. nicht erkannt.... so etwas merkt man dann erst beim zweiten send (der erste läuft ins Nirvana).
Gruss
Programmierhans
PS: Hatte ich noch so in Erinnerung... hatte damals allerdings für die Tests entweder das Netzkabel gezogen oder den VPN beendet... und dies alles ist dann jeweils direkt am PC (und nicht irgendwo auf der gerouteten Strecke).
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Hallo,
Können wir uns darauf einigen, dass mit meiner "Lösung" ein grosser Teil der Unterbrüche sehr schnell erkannt wird.
Ja, sicher. Dafür scheint die Poll
-Methode ja auch gemacht zu sein 🙂
Bei kritischen Anwendungen reicht es aber nicht.
Das isConnected =Socket.Available > 0;
finde ich seltsam.
Das sollte man eher isTransferring
oder so nennen, denn ich kann ja Connect
ausführen, aber solage ich nichts sende, ist auf der Gegenseite eben Available == 0
trotz bestehender Verbindung.
EDIT: Du hast wohl recht:
Wenn Poll
true zurückgibt, aber keine Daten vorhanden sind, müsste das bedeuten, daß kein Client verbunden ist - das steht zwar nicht explizit in der Doku, kann aber so impliziert werden.
In dem else
-Zweig müsste man IMHO jedoch um sicher zu gehen Poll
noch einmal mit SelectError
aufrufen.
Damit würde man dann nur die erwähnten Fehler einer physikalischen Trennung verpassen.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Bei kritischen Anwendungen reicht es aber nicht.
Ja das ist so... Entweder zyklisch nullers schicken oder sich von der Gegenstelle die Daten quittieren lassen ... So läuft es auch bei allen Schnittstellen zu SPS usw.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...