CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Apr 2007
    Posts
    90

    WSARecv() for IOCP

    I have problem about WSARecv() in IOCP , the second parameter of WSABUF, if my buffer length is less than the actual message size how can get the rest of the data ? just make another call to WSARecv() ? Thanks.

  2. #2
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: WSARecv() for IOCP

    Yes, simply call it again.

  3. #3
    Join Date
    Apr 2007
    Posts
    90

    Re: WSARecv() for IOCP

    Thanks for the prompt reply, but when I called it again I get the dwBytesTransfered which is the second parameter of GetQueuedCompletionStatus as 0 . Also, after I called WSARecv() I never get the error WSAEMSGSIZE which tell message was too large to fit into the specified buffer. Is this message for UDP socket only ? because I am using TCP stream socket. How can I detect my specified buffer was not enough to receive the message ?

  4. #4
    Join Date
    Dec 2002
    Location
    St.Louis MO, USA
    Posts
    672

    Re: WSARecv() for IOCP

    yes WSAEMSGSIZE is used for datagram socket. Check the return value of GetQueuedCompketionStatus It might helps you.
    Quote Originally Posted by MSDN
    Return Values
    If the function dequeues a completion packet for a successful I/O operation from the completion port, the return value is nonzero. The function stores information in the variables pointed to by the lpNumberOfBytesTransferred, lpCompletionKey, and lpOverlapped parameters.

    If *lpOverlapped is NULL and the function does not dequeue a completion packet from the completion port, the return value is zero. The function does not store information in the variables pointed to by the lpNumberOfBytes and lpCompletionKey parameters. To get extended error information, call GetLastError. If the function did not dequeue a completion packet because the wait timed out, GetLastError returns WAIT_TIMEOUT.

    If *lpOverlapped is not NULL and the function dequeues a completion packet for a failed I/O operation from the completion port, the return value is zero. The function stores information in the variables pointed to by lpNumberOfBytes, lpCompletionKey, and lpOverlapped. To get extended error information, call GetLastError.

    If a socket handle associated with a completion port is closed, GetQueuedCompletionStatus returns ERROR_SUCCESS, with *lpOverlapped non-NULL and lpNumberOfBytes equal zero
    A Person who is polite is given goodness and a person who is away from Politeness is away from Goodness.

    NAUMAAN

  5. #5
    Join Date
    Apr 2007
    Posts
    90

    Re: WSARecv() for IOCP

    I have already check the return value of GetQueuedCompketionStatus, even if my WSABUF length used is less than the actual message when I called WSARecv(), the return value of GetQueuedCompketionStatus is NON-ZERO. This is my workerThread for IOCP, in case you want to view it. Thanks .
    Code:
    DWORD WINAPI workerThread(LPVOID lParam)
    {
    	DWORD dwBytesTransfered = 0, recvByte = 0, flags = 0, sentByte = 0;
    	void *lpContext = NULL;
    	OVERLAPPED *pOverlapped = NULL;
    	LPPER_HANDLE_DATA lpHandleData = NULL;
    	int nResult;
    	WSABUF wsaBuf;
    	char buffer[MAX_BUFFER_LEN];
    	wsaBuf.len = MAX_BUFFER_LEN;
    	wsaBuf.buf = buffer;
    
    	while(1)
    	{
    		//printf("DEBUG %d\n", GetLastError());
    		nResult = GetQueuedCompletionStatus(g_hCompletionPort, &dwBytesTransfered,(LPDWORD)&lpContext, &pOverlapped, INFINITE);
    		lpHandleData = (LPPER_HANDLE_DATA) lpContext;
    		
    		if(nResult == FALSE || ((nResult == TRUE) && (dwBytesTransfered == 0)))
    		{
    			printf("GetQueuedCompletionStatus ERROR : %d\n", GetLastError());
    			if(GetLastError() != 0) // application has completed successfully
    				continue;
    		}
    
    		printf("Bytes transfered/received : %d\n", dwBytesTransfered);
    		switch(lpHandleData->opCode)
    		{
    			case OP_READ:
    				memset(buffer, 0, MAX_BUFFER_LEN);
    				wsaBuf.buf = buffer;
    				wsaBuf.len = MAX_BUFFER_LEN;
    
    				if(WSARecv(lpHandleData->serverSocket, &wsaBuf, 1, &recvByte, &flags, &lpHandleData->ol, NULL) == SOCKET_ERROR)
    					if(WSAGetLastError() == WSA_IO_PENDING)
    						printf("WSARecv WSA_IO_PENDING\n");
    					else 
    						printf("WSARecv ERROR : %d\n", WSAGetLastError());
    				lpHandleData->opCode = OP_WRITE;
    
    			break;
    
    			case OP_WRITE:
    				printf("flags : %d\n", flags);
    				printf("Data received : \n%s\n", wsaBuf.buf);
    
    
    			break;
    			case OP_CONNECT: // just connected to the server
    				printf("Connected\n");
    
    				//printf("DEBUG %d\n", GetLastError());
    				//memset(&wsaBuf, 0, sizeof(wsaBuf));
    				memset(buffer, 0, sizeof(buffer));
    				memset(&lpHandleData->ol, 0, sizeof(lpHandleData->ol));
    //\r\nConnection: close
    				sprintf(buffer, "GET / HTTP/1.1\r\nConnection: close\r\nHost: %s\r\n\r\n", lpHandleData->host);
    				wsaBuf.buf = buffer;
    				wsaBuf.len = strlen(buffer);
    
    				lpHandleData->opCode = OP_READ;
    				if(WSASend(lpHandleData->serverSocket, &wsaBuf, 1, &sentByte, flags, &lpHandleData->ol, FALSE) == SOCKET_ERROR)
    				{
    					if(WSAGetLastError() == WSA_IO_PENDING)
    						printf("WSASend WSA_IO_PENDING\n");
    					else printf("WSASend ERROR : %d\n", WSAGetLastError());
    				}
    				else printf("WSASend complete immediately.\n");
    			break;
    		}
    	}
    
    	return 0;
    }

  6. #6
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: WSARecv() for IOCP

    Quote Originally Posted by keenlearner
    Thanks for the prompt reply, but when I called it again I get the dwBytesTransfered which is the second parameter of GetQueuedCompletionStatus as 0 .
    A zero for dwBytesTransferred means that the connection was closed by the peer. You should call closesocket() and cloe the socket.
    Also, after I called WSARecv() I never get the error WSAEMSGSIZE which tell message was too large to fit into the specified buffer. Is this message for UDP socket only ?
    As Nauman has indicated, this error is for UDP only. You will not see it for TCP.
    because I am using TCP stream socket. How can I detect my specified buffer was not enough to receive the message ?
    There's no need to "detect" anything. If you are expecting more data, simply call WSARecv() again.

    Make certain that you are expecting more data, however. You should be using some kind of protocol, that you impose at the application level, to tell the recipient how much data he should expect to receive.

    Mike

  7. #7
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: WSARecv() for IOCP

    I just noticed that your worker thread uses the same "buffer" for both sends and recvs. That's an incorrect architecture for IOCP. You need to use a separate, unique buffer for each send and recv, commonly referred-to as a "per I/O buffer", and normally defined inside of a per-I/O structure. A pointer to this structure is returned to you in the lpOverlapped parameter of GetQueuedCompletionStatus.

    Mike

  8. #8
    Join Date
    Apr 2007
    Posts
    90

    Re: WSARecv() for IOCP

    Now the WSARecv() return the subsequent data after the subsequent call, and you are right I should have WSABUF in the PER_IO_DATA sructure. Thanks so much.

  9. #9
    Join Date
    Nov 2010
    Posts
    1

    Re: WSARecv() for IOCP

    Hi! I found this thread because i have a similar probem. I need change traffic on fly and i dicide use lsp to achive that! So as example i use microsoft example ftp://ftp.microsoft.com/bussys/Winso...k2/layered.zip
    But i have a problem with reallocating lpBuffers variable in WSPRecv function to add in some data.
    How i can do that and can you give me your implementation of y code which posted in this thread?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured