Gelöscht



  • Das "reactive IO" Modell (auch als "asynchronous IO" bekannt)

    Falsch



  • flasch schrieb:

    Das "reactive IO" Modell (auch als "asynchronous IO" bekannt)

    Falsch

    Genaugenommen falsch, von mir aus.

    Wenn allerdings irgendwo bloss "asynchronous IO" steht, ohne weitere Angaben, und es um Sockets geht, dann ist normalerweise das reaktive Modell gemeint. Genauer: select().



  • The Reactor patterns involve synchronous I/O, whereas the Proactor pattern involves asynchronous I/O

    http://www.artima.com/articles/io_design_patterns2.html

    http://en.wikipedia.org/wiki/Reactor_pattern



  • Irgendwas zu zitieren ändert nichts daran dass der Begriff in der Art verwendet wird, wie er nunmal verwendet wird.

    Siehe auch http://en.wikipedia.org/wiki/Asynchronous_I/O - wenn du aufpasst wird dir vielleicht auffallen dass dort explizit select() erwähnt wird. select() mit non-blocking Sockets ist nunmal asynchron.

    EDIT: oder auch hier: http://www.ibm.com/developerworks/linux/library/l-async/index.html
    Absatz "Asynchronous blocking I/O"



  • sk0r schrieb:

    Hallo,

    wie kann ich per WinSocks als Server überprüfen,
    ob ein Client nicht mehr verbunden ist? Ich habe nämlich
    eine struct, welche Events bereitstellt, u.a. auch OnDisconnect.
    Wie kann ich nun überprüfen, ob ein Client nicht mehr mit dem
    Server verbunden ist, wegen welchem Grund auch immer?!

    MfG: sk0r

    Hi,

    verwende WSAEventSelect() oder WSAAsyncSelect() (wenn Du eine GUI hast) so kannst Du auf das FD_CLOSE - Event oder FD_CLOSE - Nachricht warten lassen, ohne Schleife.

    Ein (noch unfertiges) Beispiel eines Client-Threads mit WSAEventSelect(), hier werden: FD_READ und FD_CLOSE ausgewertet:

    DWORD WINAPI MOSVR_ClientThread(SOCKET hClient){
    	SOCKET mySock = hClient;
    	static char *si = MOSVR_GetResString(300);
    
    	::send(mySock, si, strlen(si), 0);
    
    	WSAEVENT wEvent = ::WSACreateEvent();
    	if(wEvent == WSA_INVALID_EVENT) return 1;
    	if(::WSAEventSelect(mySock, wEvent, FD_CLOSE | FD_READ) == SOCKET_ERROR) return 1;
    	WSAEVENT wEar[1] = { wEvent };
    	WSANETWORKEVENTS wE;
    
    	for(;;){
    		ZeroMemory(&wE, sizeof(wE));
    
    		DWORD dwrVal = ::WSAWaitForMultipleEvents(1, wEar, false, WSA_INFINITE, false);
    		if(dwrVal == WSA_WAIT_FAILED) break;
            if(::WSAEnumNetworkEvents(mySock, wEar[0], &wE) != SOCKET_ERROR){
    			switch(wE.lNetworkEvents){
    				case FD_READ:
    					MOSVR_ReadClientCommands(mySock);
    					break;
    				case FD_CLOSE:
    					::WSACloseEvent(wEvent);
    					::closesocket(mySock);
    					return 0;
    			}
    		}
    		::WSAResetEvent(wEar[0]);
    	}
    
    	::WSAEventSelect(mySock, wEvent, 0);
    	::WSACloseEvent(wEvent);
    	::closesocket(mySock);
    	return 0;
    }
    

    Der Client läuft in einem Service, hier ist eine GUI nicht möglich.



  • ...



  • Der "beliebteste" Fehler beim Thema Socket-Programmierung, ist, dass Leute glauben "recv" würde "Pakete" empfangen, so wie sie mit "send" abgeschickt werden. Das ist nicht so. Es gibt bei Stream-Sockets keine "Paketgrenzen" oder "Nachrichtengrenzen". Wenn du 2x send mit je 100 Byte machst, kann es sein, dass ein einziges recv die ganzen 200 Byte empfängt. Oder auch nur 150 byte, oder gar nur 1 Byte.

    Was mich gleich zum zweit-beliebtesten Fehler bringt: manche Leute nehmen an dass recv genau so viel Byte empfängt wie man "verlangt". Das ist auch nicht so. recv empfängt von 1 bis N Byte, bzw. bei nonblocking Sockets von 0 bis N Byte.

    Lies die Doku, sehr genau, steht alles drin was man wissen muss 😉



  • ...



  • http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx
    die Doku ist teilweise auch auf Deutsch verfügbar, recv() gehört aber glaube ich nicht dazu...



  • ...


Anmelden zum Antworten