Laden...

(Socket) Prüfen ob Client/Server noch online sind

Erstellt von Dasart vor 13 Jahren Letzter Beitrag vor 13 Jahren 9.568 Views
D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren
(Socket) Prüfen ob Client/Server noch online sind

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

3.170 Beiträge seit 2006
vor 13 Jahren

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

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

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.

3.170 Beiträge seit 2006
vor 13 Jahren

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

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

Danke so werde ich es lösen.

C
2.121 Beiträge seit 2010
vor 13 Jahren

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.

3.170 Beiträge seit 2006
vor 13 Jahren

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

C
2.121 Beiträge seit 2010
vor 13 Jahren

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.

3.170 Beiträge seit 2006
vor 13 Jahren

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

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

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.

4.221 Beiträge seit 2005
vor 13 Jahren

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...

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo Programmierhans,

ich denke nicht daß man mit Poll und Available auskommt, denn

  1. Available kann 0 sein, und die Verbindung trotzdem bestehen.
  2. Poll mit SelectRead kann auch true zurückgeben, wenn die Verbindung geschlossen wurde.
  3. In der Doku von Socket.Poll, unter Hinweise, steht:

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

4.221 Beiträge seit 2005
vor 13 Jahren

@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...

3.170 Beiträge seit 2006
vor 13 Jahren

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

4.221 Beiträge seit 2005
vor 13 Jahren

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...

D
Dasart Themenstarter:in
25 Beiträge seit 2010
vor 13 Jahren

Ich habe beides Implementiert und es funktioniert wunderbar..