einen mit beginthread begonnen thread schließen



  • Das "connect" kommt ja irgendwann selber zurück, und dann muss er halt ein Flag abfragen, welches angibt oder der Thread schon "beendet" wurde... und muss sich eben beenden.

    Du kannst auch den Socket "schliessen", dann sollte das connect auch sofort zurückkommen und dann auf das Flag achten...



  • wie schließe ich den socket?



  • closesocket

    MSDN schrieb:

    Any pending blocking, asynchronous calls issued by any thread in this process are canceled without posting any notification messages.



  • aber wenn ich auf Start Server wieder klicke sollte es dann nochmal verbinden und das scheint nicht zu funktionieren nach einem aufruf von closesocket auf die 3 sockets



  • Du machst ja ein "bind"!
    Ich denke, Du solltest Dein ganzes System überdenken...

    Ich würde die ganzen Threads *immer* laufen lassen und nur nach einen Verbindungsversich *vor* einem "accept" prüfen, ob der Server "läuft". Damit hast Du mit den Threads nie Probleme!



  • danke! eine gute lösung



  • sorry ich muss das nochmal auffassen.
    Hier mal mein derzeitiger Code:

    SOCKET connectSocket(unsigned port)
    {
    	WSADATA wsa;
    	SOCKADDR_IN addr;
    	SOCKET acceptSocket, connectedSocket;
    	if(WSAStartup(MAKEWORD(2,0), &wsa) != 0)
    	{
    		return SOCKET_ERROR;
    	}
    	acceptSocket = socket(AF_INET,SOCK_STREAM,0);
    	if(acceptSocket==INVALID_SOCKET)
    	{
    		return SOCKET_ERROR;
    	}
    	memset(&addr,0,sizeof(SOCKADDR_IN));
    	addr.sin_family=AF_INET;
    	addr.sin_port=htons(port);
    	addr.sin_addr.s_addr=INADDR_ANY;
    	if(bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
    	{
    		return SOCKET_ERROR;
    	}
    	if(listen(acceptSocket,10)==SOCKET_ERROR)
    	{
    		return SOCKET_ERROR;
    	}
    	if(socketoption == TRUE)
    	{
    		connectedSocket=accept(acceptSocket,NULL,NULL);
    		if(connectedSocket==INVALID_SOCKET)
    		{
    			return SOCKET_ERROR;
    		}
    		return connectedSocket;
    	}
    	else
    		return 1002;
    }
    
    void Thread1 (PVOID pvoid)
    {
    	while(1)
    	{
    		s1 = connectSocket(450);
    		if(s1 == SOCKET_ERROR)
    		{
    			SetDlgItemText(FindWindow(0, ""), IDC_BUTTON2, "Start Server");
    			MessageBox(0, "Konnte nicht verbinden!", szAppName, MB_ICONERROR);
    		}
    		else if(s1 == 1002)
    		   	;
    		else
    		{
    			break;
    		}
    		Sleep(100);
    	}
        _endthread () ;
    }
    
    void Thread2 (PVOID pvoid)
    {
    	while(1)
    	{
    		s2 = connectSocket(451);
    		if(s2 == SOCKET_ERROR)
    		{
    			SetDlgItemText(FindWindow(0, ""), IDC_BUTTON2, "Start Server");
    			MessageBox(0, "Konnte nicht verbinden!", szAppName, MB_ICONERROR);
    		}
    		else if(s2 == 1002)
    			;
    		else
    		{
    			break;
    		}
    		Sleep(100);
    	}
        _endthread () ;
    }
    
    void Thread3 (PVOID pvoid)
    {
    	while(1)
    	{
    		s3 = connectSocket(452);
    		if(s3 == SOCKET_ERROR)
    		{
    			SetDlgItemText(FindWindow(0, ""), IDC_BUTTON2, "Start Server");
    			MessageBox(0, "Konnte nicht verbinden!", szAppName, MB_ICONERROR);
    		}
    		else if(s3 == 1002)
    			;
    		else
    		{
    			SetDlgItemText(FindWindow(0, "Watch Out"), IDC_BUTTON2, "Connected");
    			break;
    		}
    		Sleep(100);
    	}
        _endthread () ;
    }
    

    Die 3 Threads werden gleich bei Programmstart gestartet.
    natürlich ist socketoption aber dann noch FALSE da man noch nicht auf Start Server geklickt hat. und wenn es FALSE ist macht es nichts und geht gleich die schleife nochmal durch. Hierbei kommt natürlich wieder der connect code aber man kann ja nur 1 mal pro port binden. das heißt das es beim 2. durchlauf gar nicht mehr klappen würde. wie würdet ihr das lösen?



  • ich hab die abfrage jetzt einfach über den ganzen connectteil gemacht.

    Noch ne andere Frage:
    Wenn der Client beendet wird, welchen wert hat dann Socket_error damit ich abfragen kann ob es ein fehler war oder ob der client beendet wurde?



  • psuh



  • Das einfachste ist immer noch in die Doku zu schauen...
    z.B. bei "recv":

    If the socket is connection oriented and the remote side has shut down the connection gracefully, and all data has been received, a recv will complete immediately with zero bytes received. If the connection has been reset, a recv will fail with the error WSAECONNRESET.



  • recvBack = recv(s1, (char *)&length, sizeof(length), 0);
    if(recvBack  == WSAECONNRESET) MessageBox(0, "", "", 0);
    

    so funktioniert es jedenfalls nicht. wenn der client geschlossen ist tut sich nix



  • Dann ist die Frage, wie der Client geschlossen wird...
    Aber "recv" kommt schon sofort zurück, oder nicht? Wenn nicht, dann schliess der Client die Verbindung nicht korrekt; stört aber auch nicht, da denn irgendwan der Timeout kommt.



  • server:

    recvBack = recv(s1, (char *)&length, sizeof(length), 0);
    		if(recvBack  == WSAECONNRESET)
    		{
    			MessageBox(0, "Client has been closed!", szAppName, 0); 
    			SendMessage(FindWindow(0, "progname"), WM_COMMAND, IDCANCEL, 0); 
    		}
    

    client:

    case WM_DESTROY:
    		  closesocket(s);
    		  WSACleanup();
              PostQuitMessage (0) ;
              return 0 ;
    


  • markusxxx schrieb:

    recvBack = recv(s1, (char *)&length, sizeof(length), 0);
    		if(recvBack  == WSAECONNRESET)
    

    Ähh... Du hast aber schon die Doku zu "recv" gelesen, oder???

    Falls nicht, dann hol das mal schleunigst nach!



  • recvBack = recv(s1, (char *)&length, sizeof(length), 0);
    		if(recvBack == SOCKET_ERROR && GetLastError() == WSAECONNRESET)
    		{
    			MessageBox(0, "Client has been closed!", szAppName, 0); 
    			SendMessage(FindWindow(0, "progname"), WM_COMMAND, IDCANCEL, 0); 
    		}
    

    funktioniert nicht 😞



  • MSDN schrieb:

    If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.



  • hm jeder sagt was anderes. Soll ich jetzt 0 oder den Error code von Jochen abfragen?



  • heul langsam nervts nichts klappt -.-

    recvBack = recv(s1, (char *)&length, sizeof(length), 0);
    		if(recvBack == 0)
    		{
    			MessageBox(0, "Client has been closed!", szAppName, 0); 
    			SendMessage(FindWindow(0, "name"), WM_COMMAND, IDCANCEL, 0); 
    		}
    

    geht natürlich auch nicht. Es scheint so als würde recv die kontrolle nicht mehr zurückgeben



  • hat keiner eine Idee?



  • geht natürlich auch nicht. Es scheint so als würde recv die kontrolle nicht mehr zurückgeben

    Ja, recv ist blockierend. Lies die MSDN.
    Simon


Anmelden zum Antworten