10093 bei Nutzung von select mit WIN-Sockets



  • wollte einen kleinen server schreiben, der eingehende verbindungen verwaltet.
    bind(), accept funktionieren soweit ganz gut, aber bei select bekomme ich immer ein 10093.
    Unter linux funktioniert der code soweit tadellos. allerdings verstehe ich nich genau warum sich das select unter windows anders verhält. bisher teste ich das programm unter virtualbox mit WIN7+telnet. weis nicht genau ob ich richtig in der forum rubrik bin. denke das problem ist schon etwas kniffliger.

    /*
     * Set of connected client socket FD's
     */
    fd_set m_ClientFDSet;
    
    int AbsServer::ServerCreateFDSet() {
    	int iGreatestFD = 0;
    	for(std::list<ClientData>::iterator it = m_lClients.begin(); it != m_lClients.end(); it++) {
    		if(it->m_iSocketClient > iGreatestFD)
    			iGreatestFD = it->m_iSocketClient;
    		FD_SET(it->m_iSocketClient, &m_ClientFDSet);
    	}
    	return iGreatestFD;
    }
    
    void AbsServer::ServerLoop() {
    	int iGreatestFD;
    	Socket SocketClient;
    
    	/*
    	 * Tastatur Windows
    	 */
    	#ifndef WIN32 // UNIX, Linux
    		ServerAddClient(STDIN_FILENO);
    	#else	// WIN32
    		CreateThread(0, 0, (LPTHREAD_START_ROUTINE)KeybrdThrd, (LPVOID)this, 0, 0);
    	#endif
    
    	while(true) {
    		FD_ZERO(&m_ClientFDSet);
    
    		iGreatestFD = ServerCreateFDSet();
    
    		#ifdef WIN32
    		FD_SET((unsigned int)m_SocketServer, &m_ClientFDSet);
    		#else // UNIX, Linux..
    		FD_SET(m_SocketServer, &m_ClientFDSet);
    		#endif
    
    		if(m_SocketServer > iGreatestFD) {
    			iGreatestFD = m_SocketServer;
    		}
    
    		int iComp = -1;
    		#ifdef WIN32
    		iComp = SOCKET_ERROR;
    		#endif
    		if(iComp == select(iGreatestFD + 1, &m_ClientFDSet, NULL, NULL, NULL) ) {
    			printf("select() error\n");
    			#ifdef WIN32
    				printf( "Last error code: %d\n", WSAGetLastError() );
    				WSACleanup();
    			#endif
    		}
    		/*
    		 * neue clients
    		 */
    		if(FD_ISSET(m_SocketServer, &m_ClientFDSet)) {
    			SocketClient = m_SocketServer.Accepted();
    			ServerAddClient(SocketClient);
    		}
    		/*
    		 * Tastatur UNIX, Linux
    		 */
    		#ifndef WIN32 // UNIX, Linux
    		else if(FD_ISSET(STDIN_FILENO, &m_ClientFDSet)) {
    			HandleServer();
    		}
    		#endif
    		/*
    		 * eingehende nachrichten
    		 */
    		else {
    			for(std::list<ClientData>::iterator it = m_lClients.begin(); it != m_lClients.end(); it++) {
    				if(it->m_SocketClient == GetSendingClient()) {
    					SocketClient = it->m_SocketClient;
    				}
    			}
    			HandleClient(SocketClient);
    		}
    	}
    }
    


  • Setze den ersten Parameter von select() mal auf 0 für Windows. Vielleicht klappts, hatte da mal sowas gelesen..

    Edit:
    Sag mal.. rufst du überhaupt WSAStartup() auf?



  • ich rufe WSAStartup() erfolgreich auf (in der main). allerdings klappts mit dem select auch mit ner 0 als ersten parameter nicht.
    irgendwie verstehe ich überhaupt nicht was da schief läuft, weil der error code überhaupt keinen sinn ergibt.



  • Hm.. da fällt mir jetzt auch nichts zu ein. Der Fehlercode sollte eigentlich schon korrekt sein.
    Wenn du ein für Windows kompilierbares Minimalbeispiel basteln kannst, sehe ich mir das mal an.



  • Zu Fehler 10093 gehört auch:

    The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks)
    

    Btw: Greatest->Großartigster. Nimm Highest oder so.



  • aber ich erstelle, wie man sieht, auch kein socket innerhalb eines eigenen tasks, sondern in meiner klasse. das serversocket ist ein member, und das client socket ist in der funktion. das einzige was bei mir unter windows in einem thread läuft ist mein konsoleneingabe mit cin>>



  • Ich meinte damit, dass du evtl einen ungültigen Socket irgendwo da drin hast. Und zufällig wurde ein Socket mit genau diesem Handle-Wert in irgendeinem anderen Prozess erstellt. Oder so. Jedenfalls ist ja unzweifelhaft irgendwo der Wurm drin.

    Sonst zeig mal mehr Code, da kann ich jetzt wirklich nichts kaputtes entdecken. Nur der cast des Server-Sockets zum "unsigned int" ist merkwürdig, sollte nicht nötig sein.



  • Socketer schrieb:

    Btw: Greatest->Großartigster. Nimm Highest oder so.

    Deswegen sagt man ja auch Highest Common Divisor, oder wie 🙄
    http://en.wikipedia.org/wiki/Greatest_common_divisor



  • nfds is the highest-numbered file descriptor



  • @the great fd:
    Falls das falsch ankam: ich wollte damit nicht behaupten dass "highest" in diesem Fall nicht besser wäre. Ich denke nämlich auch dass "highest" hier besser passt. Nur dass "greatest" eben nicht falsch ist.



  • Danke für die Berichtigung, ich kannte "greatest" echt nur als "Großartigster". War mir da wohl zu sicher.

    dgrat_2, hast du noch Interesse an Hilfe?



  • ich würde sehr gerne noch hilfe in anspruch nehmen, da ich ehrlich gesagt keine ahnung habe warum das ganze im detail nicht unter window läuft.
    ich hatte grade ne eingebung und weis was schief gelaufen ist. ich habe im destruktor von einem socket wsa_cleanup aufgerufen. das gilt dann aber leider für alle sockets ):



  • Hm, komische Sache. Ich hatte WSANOTINITIALISED (10093) eigentlich immer nur wenn WSAStartup() nicht oder nicht erfolgreich aufgerufen wurde.

    Socketer schrieb:

    Zu Fehler 10093 gehört auch:

    The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks)
    

    Ich frage mich was hier mit "task" gemeint ist. WSAStartup() gilt auf jeden Fall Prozessweit, das muss man nicht wie CoInitialize() o.ä. pro Thread wiederholen.
    Möglicherweise ein Überbleibsel aus alten Tagen? (Hiessen Prozesse unter Windows vielleicht mal Tasks -- zu Zeiten vor Win32 vielleicht?)

    @dgrat_2:
    Wie schon gesagt, ich hatte WSANOTINITIALISED noch nie mit erfolgreichem WSAStartup(). Von daher ... prüf das nochmal nach. Step im Debugger durch, oder gibt alle möglichen Werte aus (printf). Inklusive Returnwert von WSAStartup, und auch die Werte aller Socket-Descriptoren. Und mach auch nen Breakpoint bzw. ne TRACE()/printf() Ausgabe zu jedem WSACleanup() Aufruf in deinem Programm...



  • also, der fehler war, dass ich in meiner eigenen socket classe den wsa-socket thread beendet habe und das dann für alle sockets in meinem programm gilt. das programm läuft nun auch unter windows wie vorgesehen.
    allerdings finde ich den weg, wie windows sockets behandelt irgendwie nicht so gut wie unter linux, wo man alle filedescriptoren wie sockets oder umgekehrt behandelt. außerdem muss man da auch keine kryptischen prozesse starten wo keiner weis was die machen.



  • dgrat_2 schrieb:

    allerdings finde ich den weg, wie windows sockets behandelt irgendwie nicht so gut wie unter linux, wo man alle filedescriptoren wie sockets oder umgekehrt behandelt.

    Aha.

    außerdem muss man da auch keine kryptischen prozesse starten wo keiner weis was die machen.

    Was für "kryptischen Prozesse" meinst du bitte?


Anmelden zum Antworten