Verstädnisfragen iocp



  • Moin,

    schreibe gerade an einem iocp handler für meine Bibliothek habe mich dazu win7 sdk gehalten.

    Warum kein WSARecv beim case ClientIoRead aufgerufen wird stattdessen bei ClientIoAccept. Nächste frage warum niemals bei mir der case ClientIoRead eintriftt.

    Der komplette Code ist unter https://github.com/Tuxist/libhttppp einzusehen.

    switch (lpIOContext->IOOperation) {
    		case ClientIoAccept: {
    
    			//
    			// When the AcceptEx function returns, the socket sAcceptSocket is 
    			// in the default state for a connected socket. The socket sAcceptSocket 
    			// does not inherit the properties of the socket associated with 
    			// sListenSocket parameter until SO_UPDATE_ACCEPT_CONTEXT is set on 
    			// the socket. Use the setsockopt function to set the SO_UPDATE_ACCEPT_CONTEXT 
    			// option, specifying sAcceptSocket as the socket handle and sListenSocket 
    			// as the option value. 
    			//
    			SOCKET sock = _QueueIns->_ServerSocket->getSocket();
    
    			nRet = setsockopt(
    				lpPerSocketContext->pIOContext->SocketAccept,
    				SOL_SOCKET,
    				SO_UPDATE_ACCEPT_CONTEXT,
    				(char *)&sock,
    				sizeof(sock)
    			);
    
    			if (nRet == SOCKET_ERROR) {
    
    				//
    				//just warn user here.
    				//
    				//printf("setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed to update accept socket\n");
    				WSASetEvent(_QueueIns->_CleanupEvent[0]);
    				return(0);
    			}
    
    			lpAcceptSocketContext = _QueueIns->UpdateCompletionPort(
    				lpPerSocketContext->pIOContext->SocketAccept,
    				ClientIoAccept, TRUE);
    
    			if (lpAcceptSocketContext == NULL) {
    
    				//
    				//just warn user here.
    				//
    				//printf("failed to update accept socket to IOCP\n");
    				WSASetEvent(_QueueIns->_CleanupEvent[0]);
    				return(0);
    			}
    
    			//
    			// Add connection to connection handler
    			//
    			curcon = _QueueIns->addConnection();
    			ClientSocket *clientsocket = curcon->getClientSocket();
    			clientsocket->setSocket(lpAcceptSocketContext->Socket);
    			printf("aceppt connection on port: %d\n", clientsocket->getSocket());
    
    			if (dwIoSize) {
    				lpAcceptSocketContext->pIOContext->IOOperation = ClientIoWrite;
    				lpAcceptSocketContext->pIOContext->nTotalBytes = dwIoSize;
    				lpAcceptSocketContext->pIOContext->nSentBytes = 0;
    				lpAcceptSocketContext->pIOContext->wsabuf.len = dwIoSize;
    				hRet = StringCbCopyN(lpAcceptSocketContext->pIOContext->Buffer,
    					BLOCKSIZE,
    					lpPerSocketContext->pIOContext->Buffer,
    					sizeof(lpPerSocketContext->pIOContext->Buffer)
    				);
    				lpAcceptSocketContext->pIOContext->wsabuf.buf = lpAcceptSocketContext->pIOContext->Buffer;
    
    				nRet = WSASend(
    					lpPerSocketContext->pIOContext->SocketAccept,
    					&lpAcceptSocketContext->pIOContext->wsabuf, 1,
    					&dwSendNumBytes,
    					0,
    					&(lpAcceptSocketContext->pIOContext->Overlapped), NULL);
    
    				if (nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError())) {
    					//printf("WSASend() failed: %d\n", WSAGetLastError());
    					_QueueIns->CloseClient(lpAcceptSocketContext, FALSE);
    				}
    			}
    			else {
    
    				//
    				// AcceptEx completes but doesn't read any data so we need to post
    				// an outstanding overlapped read.
    				//
    				lpAcceptSocketContext->pIOContext->IOOperation = ClientIoRead;
    				dwRecvNumBytes = 0;
    				dwFlags = 0;
    				buffRecv.buf = lpAcceptSocketContext->pIOContext->Buffer,
    				buffRecv.len = BLOCKSIZE;
    				nRet = WSARecv(
    					lpAcceptSocketContext->Socket,
    					&buffRecv, 1,
    					&dwRecvNumBytes,
    					&dwFlags,
    					&lpAcceptSocketContext->pIOContext->Overlapped, NULL);
    
    				if (nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError())) {
    					//myprintf("WSARecv() failed: %d\n", WSAGetLastError());
    					_QueueIns->CloseClient(lpAcceptSocketContext, FALSE);
    				}
    			}
    
    			//
    			//Time to post another outstanding AcceptEx
    			//
    			if (!_QueueIns->CreateAcceptSocket(FALSE)) {
    				//myprintf("Please shut down and reboot the server.\n");
    				WSASetEvent(_QueueIns->_CleanupEvent[0]);
    				return(0);
    			}
    			break;
    		}
    
    		case ClientIoRead: {
    
    			//
    			// a read operation has completed, post a write operation to echo the
    			// data back to the client using the same data buffer.
    			//
    			lpIOContext->IOOperation = ClientIoWrite;
    			lpIOContext->nTotalBytes = dwIoSize;
    			lpIOContext->nSentBytes = 0;
    			lpIOContext->wsabuf.len = dwIoSize;
    			dwFlags = 0;
    			if (nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError())) {
    				//myprintf("WSASend() failed: %d\n", WSAGetLastError());
    				_QueueIns->CloseClient(lpPerSocketContext, FALSE);
    				_QueueIns->DisconnectEvent(curcon);
    				_QueueIns->delConnection(curcon);
    				break;
    			}
    			curcon = _QueueIns->getConnection(lpAcceptSocketContext->Socket);
    			if(curcon)
    			  _QueueIns->RequestEvent(curcon);
    			printf("read\n");
    			break;
    		}
    
    		case ClientIoWrite: {
    
    			//
    			// a write operation has completed, determine if all the data intended to be
    			// sent actually was sent.
    			//
    			lpIOContext->IOOperation = ClientIoWrite;
    			lpIOContext->nSentBytes += dwIoSize;
    			dwFlags = 0;
    			if (lpIOContext->nSentBytes < lpIOContext->nTotalBytes) {
    
    				//
    				// the previous write operation didn't send all the data,
    				// post another send to complete the operation
    				//
    				buffSend.buf = lpIOContext->Buffer + lpIOContext->nSentBytes;
    				buffSend.len = lpIOContext->nTotalBytes - lpIOContext->nSentBytes;
    				nRet = WSASend(
    					lpPerSocketContext->Socket,
    					&buffSend, 1, &dwSendNumBytes,
    					dwFlags,
    					&(lpIOContext->Overlapped), NULL);
    				if (nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError())) {
    					//myprintf("WSASend() failed: %d\n", WSAGetLastError());
    					_QueueIns->CloseClient(lpPerSocketContext, FALSE);
    					_QueueIns->DisconnectEvent(curcon);
    					_QueueIns->delConnection(lpAcceptSocketContext->Socket);
    				}
    			}
    			else {
    
    				//
    				// previous write operation completed for this socket, post another recv
    				//
    				lpIOContext->IOOperation = ClientIoRead;
    				dwRecvNumBytes = 0;
    				dwFlags = 0;
    				buffRecv.buf = lpIOContext->Buffer,
    					buffRecv.len = BLOCKSIZE;
    				nRet = WSARecv(
    					lpPerSocketContext->Socket,
    					&buffRecv, 1, &dwRecvNumBytes,
    					&dwFlags,
    					&lpIOContext->Overlapped, NULL);
    				if (nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError())) {
    					//myprintf("WSARecv() failed: %d\n", WSAGetLastError());
    					_QueueIns->CloseClient(lpPerSocketContext, FALSE);
    					_QueueIns->DisconnectEvent(curcon);
    					_QueueIns->delConnection(lpAcceptSocketContext->Socket);
    				}
    			}
    			break;
    		}
    		} //switch
    

Anmelden zum Antworten