Winsockets, geschlossene Verbundung? Wie Feststellen?



  • Ich habe eine Library, die die Stream-Sockets OO umhüllt. Ich biete eine Funktion, die so etwas wie Select() bietet, nur überlasse ich das Empfange und Senden von Daten dem User der Lib.

    Problem: Select() meint, dass neue Daten anliegen, wenn ein Client die
    Verbindung schließt.
    Ich kann nicht feststellen ob der Client die Verbindung geschlossen hat,
    ohne recv() aufzurufen. [recv() == SOCKET_ERROR]

    Suche: Eine funktion außer recv() um zu prüfen ob die Verbindung noch steht.

    Kann mir jemand helfen? Danke im voraus!

    Ps.: Ansonsten müsste ich hässlich eine Methode wie: SocketIsDead(...) bereitstellen.. 🙄



  • Hallo,

    was spricht denn dagegen, innerhalb der Klasse mit recv & MSG_PEEK zu schauen, ob es wirklich Daten zum Lesen gibt bzw. geschlossen wurde, bevor die Klasse nach außen hin was meldet?



  • SeppSchrot schrieb:

    Hallo,

    was spricht denn dagegen, innerhalb der Klasse mit recv & MSG_PEEK zu schauen, ob es wirklich Daten zum Lesen gibt bzw. geschlossen wurde, bevor die Klasse nach außen hin was meldet?

    Dann guck mal in die Winsock Lame List. :p



  • Oh, das ist nicht schön.

    Und wenn du den Weg über selbstverwalteten Puffer gehst?



  • Nur eine Idee wenn dein Client die Verbindung schließt könntest dieser
    ja kurz davor ein zeichen senden. Dann weißt du das er sich trennt.



  • Naja, es gibt ja diese Sprichwort, dass man bei Webanwendungen grundsätzlich davon ausgehen soll, dass 'die Welt da draußen' komplett schlecht ist. So auch
    die Clienten, und sei es nur, dass der Benutzer übers Kabel stolpert. (Was mir mindestens 1x die Woche passiert 😞 )



  • Ich verstehe das Problem nicht. Was ist daran so schlimm recv aufzurufen?



  • Und wie wäre es damit:
    Und zwar das der server so jede minute was zum client sendet und der darauf antwirten muss also so:
    Server zum Client: Bist du noch da?
    Client zum Server: Ja
    Das ist jetzt natürlich nur wörtlich gemeint.Also so ne automatik.



  • Das macht eigentlich das TCP schon automatisch.



  • Beim IRC Protokoll gibt es auch diese PING PONG.





  • SORRY!!! Ich hatte den Thread völlig vergessen! 😮

    Danke für all euere Posts erstmal vorweg!

    SeppSchrot schrieb:

    Hallo,

    was spricht denn dagegen, innerhalb der Klasse mit recv & MSG_PEEK zu schauen, ob es wirklich Daten zum Lesen gibt bzw. geschlossen wurde, bevor die Klasse nach außen hin was meldet?

    Ich hab noch nicht begriffen wie du das meinst, kannst du vieleicht einen Beispielcode posten? Soweit ich das jetzt verstanden habe scheint es ein recv() zu simulieren was du meinst, klingt nicht schlecht.

    hä schrieb:

    Ich verstehe das Problem nicht. Was ist daran so schlimm recv aufzurufen?

    Ich möchte mein Projekt so modular wie möglich gestalten, die Socket-Library ist eines der Module. Es hat die Aufgabe send() und recv() als Methoden bereitzustellen, nicht sie nach eigenem belieben aufzurufen. Klar, ich könnte wie von:

    Stefan311 schrieb:

    Und wie wäre es damit:
    Und zwar das der server so jede minute was zum client sendet und der darauf antwirten muss also so:
    Server zum Client: Bist du noch da?
    Client zum Server: Ja
    Das ist jetzt natürlich nur wörtlich gemeint.Also so ne automatik.

    Vorgeschlagen einfach in der Library mit etwas Overhead lösen, indem ich eine Basiskommunikation reinbaue, von der der Nutzer der Bibliothek nichts mitbekommt, aber dass würde die Flexibilität versauen, die Library wäre inkompatibel mit anderen Socket-Anwendungen, welche diese Sub-Kommunikation ["Hallo? Noch da?" <-> "Jupp, noch da..."] anders oder gar nicht implementieren.
    😞

    net schrieb:

    oder sowas: http://www.freesoft.org/CIE/RFC/1122/114.htm

    Klingt sehr interessant, auch wenn ich mir nicht sicher bin, ob ich das in vollem Umfang verstanden habe. Mir scheint das eine Diskussion über eine "Keep-Alive" Implementierung in TCP zu sein. 😕

    Implementors MAY include "keep-alives" in their TCP implementations, although this practice is not universally accepted. If keep-alives are included, the application MUST be able to turn them on or off for each TCP connection, and they MUST default to off.

    Wo soll das denn implementiert werden?? Und von wem? Schaut mir ehr aus würden die von der TCP implementierung des BS reden? Ich schätze dass muss mir jemand erklären... 🤡

    @SeppSchrot: Ich würde mich sehr über einen Tipp zur Verwendung von "recv & MSG_PEEK" freuen!

    Danke im Voraus. 🙂



  • Sowieso schrieb:

    Wo soll das denn implementiert werden?? Und von wem? Schaut mir ehr aus würden die von der TCP implementierung des BS reden? Ich schätze dass muss mir jemand erklären... 🤡

    so isses. ein tcp kann, aber muss nicht, mit keep-alives umgehen können. ein tcp welches keine keep-alives kennt, wird dadurch aber nicht gestört weil aus dessen sicht sind es gültige pakete aber ohne inhalt. das tcp in den windosen kann aber keep-alives. aktivieren kannst du das mit setsockopt(). guckst du: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/setsockopt_2.asp



  • net schrieb:

    so isses. ein tcp kann, aber muss nicht, mit keep-alives umgehen können. ein tcp welches keine keep-alives kennt, wird dadurch aber nicht gestört weil aus dessen sicht sind es gültige pakete aber ohne inhalt. das tcp in den windosen kann aber keep-alives. aktivieren kannst du das mit setsockopt(). guckst du: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/setsockopt_2.asp

    Vielen Dank! Damit kann ich was anfangen glaube ich!
    Aber.. gibt's dass auch für die BSD-Socket-API?
    Ich meine vor allem Linux und MacOS, Solaris wäre auch nicht schlecht... 🙂



  • Hier bin ich nochmal. 🙂
    Hab' das Problem einfach lösen können, - und will das niemandem vorenthalten wie ich es gemacht habe.. also:

    Ich hatte ja einen Wrapper für (erstmal nur) die WinSocketApi programmiert. Das Problem war dass ich mit ohne recv() nicht feststellen konnte ob eine Verbindung geschlossen ist. Recv() wollte ich nicht verwenden, da ich dann die Daten ja schon hätte, und das Abrufen von Daten soll ja schließlich der Nutzer des Wrappers und nicht der Wrapper machen... Lösung:
    1.) Ich habe einen Observer für die Sockets eingebaut, der über neue Daten informiert wird. Somit kann ich sicher gehen DASS recv() auch aufgerufen wird wenn Daten anliegen, .. oder eine Verbindung geschlossen wurde und es nur nach Daten ausschaut.

    2.) Die recv() Methode des Wrapper-Sockets deligiert die Operation natürlich an die API, schaut aber auf den Rückgabewert [if(return_value==SOCKET_ERROR){...}] und erkennt somit geschlossene Verbindungen. Soweit so gut, interessant ist jetzt aber noch die Frage wie das "Select-Aufrufende-Socket-Verwaltende"-Objekt von der geschlossenen Verbindung informiert wird... auch umständlich über callbacks?
    NEIN, einfach indem der API-Socket [SOCKET==int] geschlossen wird 😃
    -> dadurch fällt er bei der Überprüfung vor dem nächsten select() auf und wird erst gar nicht in das fdSet eingetragen. 💡

    Da das den User des Wrapper evtl. interessiert wird zudem noch eine abstrakte Callback-Methode aufgerufen, die von den abgeleiteten Klassen wie z.B. dem ClientSocket überschrieben werden muss. [Muss, da der Socket auch in dieser Methode geschlossen werden muss, ... da nicht jeder Socket API socket() verwendet sondern über API accept() einen Wert zugewisen bekommt wollte ich das Schließen der Sockets auch in den abgeleiteten Socket Klassen lassen)
    [Wobei es vieleicht trotzdem sinnvoller wäre dies in der recv() Methode der Basis-Socket-Klasse vorzunehmen, was meint ihr?]

    PS.: Ich bin's übrigens.. "sowieso". 🤡
    PPS.: Verbesserungsvorschläge? 🙂


Anmelden zum Antworten