Frage zum SOCKET-Status
-
Hallo,
zur Zeit bemerke ich einen Verbindungsabbruch seitens eines Client mittels
Select dann ein recv und dann schaue ich mir den Returncode des recv - Kommandos an.
Klappt wunderbar, aber ich würde gerne ab und zu im Programm den Verbindungsstatus eines Sockets ohne recv abfragen können. (Schliesslich brauch ich ja dann nicht weiterzumachen falls der Client mittlerweile weg ist)Also so etwas wie eine Funktion ála
SOCKET meinsocket; bool wert; // ... wert=ist_noch_Valid(socket); oder wert = socket.ist_noch_valid()Bei Msdn habe ich da keine entsprechende Funktion gefunden...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/recv_2.aspGibt es für so etwas eine Implementation?
Gruss
R
-
Also ich hab mir da einfach mal etwas programmiert, klappt aber leider nicht....

BOOL IsValid(SOCKET ss) { return (ss != INVALID_SOCKET); }Der liefert immer true zurück.
-
Hast du es mal mit der select()-Funktion versucht?
-
Ja.
Für jeden Client wird ein Thread gestartet, der einen zuerst Willkommen heisst.
Dann wartet der Thread auf Windowsmessages. (die natürlich vorher registeriert wurden)
Diese Messages können von der Main oder von anderen Hilfsthreads kommen.
Im Main jedenfalls wartet der Select darauf, dass was an den Sockets passiert.Kommen Daten an, erhält der entsprechende Thread von Main die Message "datenliegenan" und der holt diese dann mittels recv ab und verarbeitet diese.
Dort (im Thread) erkenne ich natürlich einen Disconnect (mittels Returnwert von recv), aber der Select im Main weiss ja noch nichts von dem Disconnect und wartet weiter auf dem (jetzt) toten Socket.
Wenn ich im Workerthread dann ein CloseSocket mache -> Bumm.
Daher würde ich gerne direkt nach dem Select wissen ob ein Verbindungsabbruch vorliegt, damit ich diesen Socket rausschmeissen kann. (Und dem entsprechenden Thread "bitteterminieren" schicken kann).Momentan sieht es so aus (nicht funktionierend):
while(1) { FD_ZERO(&fdSet); // Inhalt leeren FD_SET(acceptSocket,&fdSet); // Den Socket, der Verbindungen annimmt, hinzufügen if (MyComm.client_sockets.size()>0) //falls noch mehr da sind, die auch hinzufügen { for(i=0;i<MyComm.client_sockets.size();i++) { FD_SET(MyComm.client_sockets[i],&fdSet); }; }; rc=select(0,&fdSet,NULL,NULL,NULL); //warten bis was passiert. if(rc==SOCKET_ERROR) { printf("Fehler: select, fehler code: %s\n",WSAGetLastError()); return 1; } if(rc==INVALID_SOCKET) //das funktioniert leider nicht. { cout<<"client weg"<<endl; return 1; } for(i=0;i<MyComm.client_sockets.size();i++) //durchgehen aller sockets und den finden, wo sich was getan hat { if(FD_ISSET(MyComm.client_sockets[i],&fdSet)) { DWORD ccc; ccc=MyComm.socket_thread[MyComm.client_sockets[i]]; //threadid des clients der was bekommt if (IsValid(MyComm.client_sockets[i])) //source davon steht schon oben, funktioniert aber auch nicht. :( { cout <<"valid"<<endl; PostThreadMessage ( ccc , MyComm.socketdatamsg, 0 , 0 ); //den thread benachrichtigen, dass was vorliegt (aber hier noch nicht recv'en) } else { cout<<"client weg"; };Was mache ich denn falsch?
-
Ich hab das recv jetzt wieder ins main gepackt und dort wird es ausgewertet. Die empfangenen Daten werden über eine globale Variable übergeben.
Anders hab ich es nicht hinbekommen....
Ich hab noch ein bischen im msdn rungestöbert, und auch WSAgetsockstatus (oder so ähnlich) gefunden, und dann hätte ich auf Errorcodes testen können, aber das ist mir weit zu umständlich. Dann doch lieber das Design ordenlich machen.