TCP verbindung beenden? [gelöst]



  • Hallo!
    Ich wende mich mal wieder mit einem Problemchen an euch: Ich habe eine TCP Verbindung zwischen meinem Server & Client aufgebaut.
    Auf der Serverseite überprüfe ich die Verbindung jede Sekunde mittels

    rc = send(SocketSearch[pos],"",0,0);
    		if(rc == SOCKET_ERROR)
    		     //Verbindung beendet
    

    Das klappt auch super, wenn ich den Client ein einfach schließe. Wenn ich jedoch auf der Clientseite closesocket() aufrufe liefert rc weiterhin brav 0 zurück(habe es auch mal mit recv() probiert - passiert das Gleiche). Auch WSAGetLastError() gibt 0 zurück.
    Woran kann dies liegen? Oder habt ihr eine alternative Idee, wie ich die Verbindung kontrollieren kann?

    Vielen Dank schonmal!



  • msdn schrieb:

    Calling send with a len parameter of zero is permissible and will be treated by implementations as successful. In such cases, send will return zero as a valid value. For message-oriented sockets, a zero-length transport datagram is sent.

    Bei TCP wirst du wohl tatsächlich was senden müssen 😉



  • @geeky:
    Naja, der Client sollte ja wissen dass er ein RST bekommen hat.
    Von daher sollte er auch sofort einen Verbindungsabbruch melden können, auch ohne was zu senden.



  • Tja, es könnte so einfach sein...
    Aber leider stammt das api Design ursprünglich vom linux kernel, daher kann es ja nur auf endloses Gefrickel hinauslaufen



  • Die API kommt von den Berkeley Sockets und ist gut.

    Du mußt den Socket mit select auf einen Fehlerevent überwachen und dann bekommst du auch gemeldet das der Server ein RST Packet geschickt hat.

    MfG



  • Ich habe es nun mal mit select() versucht. Wenn ich den Client einfach schließe liefert er mir wie erwartet, dass ich lesen & schreiben kann.
    Schließe ich aber erst den Socket und beende dann den Client liefert select weiterhin kein Ergebnis. Überraschender weise wird mir jedoch niemals ein Error gemeldet

    TIMEVAL time={0,0};
    		FD_SET fd;
    		FD_ZERO(&fd);
    		FD_SET(Socket,&fd);
    		select(0,NULL,NULL,&fd,&time);
    		if(FD_ISSET(Socket,&fd))
    			MessageBox(NULL,"ERR","TST",MB_OK|MB_TOPMOST);
    
    		FD_ZERO(&fd);
    		FD_SET(Socket,&fd);
    		select(0,NULL,&fd,NULL,&time);
    		if(FD_ISSET(Socket,&fd))
    			MessageBox(NULL,"READ","TST",MB_OK|MB_TOPMOST);
    
    		FD_ZERO(&fd);
    		FD_SET(Socket,&fd);
    		select(0,&fd,NULL,NULL,&time);
    		if(FD_ISSET(Socket,&fd))
    			MessageBox(NULL,"WRITE","TST",MB_OK|MB_TOPMOST);
    

    ➡ Edit: Ok ich habe eine Möglichkeit gefunden die für mich jetzt grade klappt - ansich aber echt doof ist: wenn ich recv() nach einem closesocket() aufrufe liefert dieses 0 zurück (nicht -1, also SOCKET_ERROR). Komisch, aber dass reicht mir.

    char buf;
    	rc = recv(SocketSearch[0],&buf,1,0);
    	if(rc != 1)
    		MessageBox(NULL,"ENDE","TST",MB_OK|MB_TOPMOST);
    


  • also bei mir geht das:

    FD_SET(hSocket,&fdsRead);
    			FD_SET(hSocket,&fdsError);
    
    			if (select(0,&fdsRead,NULL,&fdsError,&tvTimout))
    			{
    				if (FD_ISSET(hSocket,&fdsError))
    				{
    					bIsConnected = false;
    				}
    
    				if (FD_ISSET(hSocket,&fdsRead))
    				{
    					if (0 < (ciRead = recv(hSocket,(char *)rgubRxBuffer,1800,0)))
    					{
    
    					}
    					else
    					{
    						bIsConnected = false;
    					}
    				}
    		 }
    

    Wenn die Verbindung verloren geht passiert es entweder das ein Error gemeldet wird oder read mit 0 zurückkommt.

    MfG


Anmelden zum Antworten