Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
(Socket) Prüfen ob Client/Server noch online sind
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

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

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

In Socket buffer addieren und prüfen ob alle Daten vorhanden sind. schreibst Du ja
Zitat von Dasart
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
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

Danke so werde ich es lösen.
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2.099

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2.099

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Programmierhans
myCSharp.de - Experte

Avatar #avatar-1651.gif


Dabei seit:
Beiträge: 4.221
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Zitat von Dasart
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...
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

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:
Zitat
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
private Nachricht | Beiträge des Benutzers
Programmierhans
myCSharp.de - Experte

Avatar #avatar-1651.gif


Dabei seit:
Beiträge: 4.221
Herkunft: Zentralschweiz

beantworten | zitieren | melden

@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...
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3.163
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,
Zitat
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
private Nachricht | Beiträge des Benutzers
Programmierhans
myCSharp.de - Experte

Avatar #avatar-1651.gif


Dabei seit:
Beiträge: 4.221
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Zitat von MarsStein
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...
private Nachricht | Beiträge des Benutzers
Dasart
myCSharp.de - Member



Dabei seit:
Beiträge: 25

Themenstarter:

beantworten | zitieren | melden

Ich habe beides Implementiert und es funktioniert wunderbar..
private Nachricht | Beiträge des Benutzers