Was macht WSACleanup(), das closesocket() nicht tut?
-
Hallo,
ich arbeite derzeit an einer Client-Server-Struktur und bisher regelte ich das erkennen von "toten" Sockets auf Serverseite so:
long status; SOCKET socket; ... status = recv(socket, ...); if (status == SOCKET_ERROR) hauweg(socket); // socket als "tot" erkanntNun habe ich am Client längere Zeit rumgepuzzelt und auf einmal erkennt es mein Server nicht mehr, wenn ich meinen Client schließe.
Ich@Krise
Dann hab ich gesehen, dass ich im Destruktor meiner Client-Socket-Klasse was geändert hatte:
Dort stand eigentlich nur:
WSACleanup();
drin und ich hatte der Vollständig halber davor noch
closesocket(socket);
gesetzt, woraufhin der Server (status == SOCKET_ERROR) nicht mehr als true erkennen konnte und der Socket im Status LAST_ACK stehen blieb.Nun ist also closesocket() wieder draußen und es funktioniert wieder, doch wie im Titel schon genannt, frag ich mich, was WSACleanup() anders oder zusätzlich tut und ob es sicherere Methoden gibt zu bestimmen, ob ein Socket noch "lebt".
Leider kommt es nämlich auch jetzt nicht selten vor, dass ein Socket angeblich noch "lebt" und dann allerdings im Status FIN_WAIT steht und der Server demnach noch weniger mitbekommen hat, da LAST_ACK AFAIK nach FIN_WAIT kommt.
Ich hoffe meine Frage ist klar geworden, ansonsten bitte nachfragen.
lg Max
PS: Eventuell wäre es sicherer neben readability mit select() auch mal writeability zu prüfen ... ?
-
WSACleanup() in der Socket Klasse?
Das ruft man normalerweise einmal am Ende des Programms auf.
-
Jup genau, ich sagte ja: im Destruktor.
Und dieser Destruktor wird erst am Ende des Programms aufgerufen
lg Max
-
Du weisst schon, dass du im komplett falschen Forum bist? Deine Sockets gehören zur WinAPI und haben mit Standard-C++ nichts am Hut!
Was der Unterschied zwischenWSACleanupundclosesocketist, kannst du gerne selber nachlesen:
WSACleanup
closesocketOb ein Socket noch lebt, weiss ich nicht wie man unter der WinAPI genau prüft. Mit anderen APIs ist das aber meistens so, dass man ein ständiges read auf dem Socket besitzt. Der Fehler, welcher von read zurückgegeben wird, kann einem sagen, wann das Socket geschlossen wurde.
Grüssli
PS: Der Destruktor wird nicht immer am Ende des Programmes aufgerufen!
-
Wenn das
closesocketauf Client-Seite aufgerufen wird, dann setzt es beim Server auch nie den Socket auf SOCKET_ERROR, sondern du bekommst nen recv-Event und wenn du dannint bla = recv (...)aufrufst, ist bla genau 0... Das signalisiert dir, dass die Verbindung erfolgreich getrennt wurde...WSACleanuphat im Übrigen nichts mitclosesocketzu tun... closesocket beendet die verbindung und wsacleanup gibt speicherplatz frei etc - es beendet auf jeden Fall alle sockets in deinem Programm (oder zumindest in dem Prozess)bevor du das nächste mal fragst: MSDN - ist echt ne tolle Erfindung... Und wie gesagt:
#include <windows.h>→ WinAPIbb
-
Nochmal anders gesagt (was unskilled schon geschrieben hat): dein Server-Programm ist falsch da es den Fall "Connection geschlossen" nicht erkennt.
-
-
Sockets gehören zur WinAPI und haben mit Standard-C++ nichts am Hut!
Noch nicht.

-
Au ja, das wär was.
#include <tcp>
#include <udp>
lg Max
-
drakon schrieb:
Sockets gehören zur WinAPI und haben mit Standard-C++ nichts am Hut!
Noch nicht.

Und ob es kommen wird ist fraglich. Jedenfalls ganz sicher noch nicht fest. Und wenn frühstens im TR2, der noch kein Veröffentlichungstermin hat. Es ist derzeit also nur eine "Idee".
Bis es soweit ist, gilt weiterhin, Boost.Asio verwenden. Genügt mir ehrlich gesagt vollkommen.

Grüssli
