News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

IOCP Server, problem with WSARecv

Started by edike123, December 05, 2010, 04:19:23 PM

Previous topic - Next topic

edike123

Hi,

   I've been working on a little IO Completion Port Server and have encountered a probably trivial problem which after a week of trying I am still not able to solve.
For the sake of clarity I will describe the main aspects of the program, it's nothing new, just a reproduction of some standard code mainly inspired by
a project found at: http://www.codeproject.com/KB/IP/iocp_server_client.aspx
 
  First I created an IO completion port, then a WSAsocket, to which a WSAEvent is associated and triggered by FD_ACCEPT, after that I invoke bind and listen  and create a  listener thread  which invokes WSAWaitForMultipleEvents, WSAEnumNetworkEvents and  WSAAccept in an infinite loop. Every incoming connection has its handle stored and is associated with the completion port. Next I create a worker thread which invokes GetQueuedCompletionStatus in an infinite loop.
So far everything worked fine, I wrote a little client which connected successfully.
 
  Next I wanted to send some data to the server from the chosen client, for this to happen I invoked WSARecv on the server side. Sadly I always got an error message from WSARecv. I'll show you how I called WSARecv:

;STRUCT DEFINES

  WSAEVENT typedef HANDLE

WSAOVERLAPPED struct
    Internal DWORD ?
    InternalHigh DWORD ?
    an_Offset DWORD ?
    OffsetHigh DWORD ?
    hEvent WSAEVENT ?
WSAOVERLAPPED ends

WSABUF struct
    len DWORD ?
    buf DWORD ?
WSABUF ends

;END STRUCT DEFINE

;DATA
 
  wbuff WSABUF <>           
  buffer DB 2000 dup (0)
  nr_bytes_received DD 0
  flag DD MSG_PARTIAL     
  ooverlapped WSAOVERLAPPED <>  ;             
;END DATA

;CODE 
    .
    .     
  lea eax, buffer
  mov wbuff.buf, eax

  mov eax, 2000
  mov wbuff.len, eax

  invoke WSARecv, client_socket, addr wbuff, 1,addr nr_bytes_received,addr flag,addr ooverlapped, NULL
  .
  .
  .
;END CODE

The error message is:  WSARecv - The system detected an invalid pointer address in attempting to use a pointer argument in a call.

Things I've tried:- modifying ooverlapped.h_Event to the handle created by WSA_CREATEEvent
                       - modifying ooverlapped.h_Event to the handle of the completion port (invalid handle)
                       - instead of using ooverlapped, I used the address of the OVERLAPPED structure returned by GETQUEUEDCOMPLETIONSTATUS  in the worker thread
                       - filling ooverlapped with zeros
                       - looking at a lot of sample code, but didn't seem to find anything different from mine.     

I just don't get it, please help me out.Thanks in advance.

jj2007

lpNumberOfBytesRecvd [out]

    A pointer to the number, in bytes, of data received by this call if the receive operation completes immediately.

    Use NULL for this parameter if the lpOverlapped parameter is not NULL to avoid potentially erroneous results. This parameter can be NULL only if the lpOverlapped parameter is not NULL.

edike123



Quote from: jj2007 on December 05, 2010, 06:26:56 PM
lpNumberOfBytesRecvd [out]

    A pointer to the number, in bytes, of data received by this call if the receive operation completes immediately.

    Use NULL for this parameter if the lpOverlapped parameter is not NULL to avoid potentially erroneous results. This parameter can be NULL only if the lpOverlapped parameter is not NULL.


jj2007, thanks for your reply!  :bg

I've already tried that (using NULL for addr nr_bytes_received, but I still get the same error message). :(

The only variation in error message occurs when I change the ooverlapped.hevent  value in the overlapped structure, the two possible errors are:
1.The handle is invalid
2.The system detected an invalid pointer address in attempting to use a pointer argument in a call.(WSAEfault)

Let me present some more specific issues, maybe these could have some relevance:

A. I use EasyCode masm
B. Could the error message be a specific  of the client_socket variable?
     I get this socket like this:

      invoke WSAAccept, listensocket, NULL, NULL, NULL, NULL
      mov client_socket, eax
         
      listensocket is bound to a sockaddr_in structure with parameters (AF_INET, IN_ADDR_ANY,port number irrelevant)

C.There's some community content in the MSDN reference for WSARecv which states that:
     
  " The Error code section of the documentation for WSARecv is incomplete. WSAEFAULT can occur if lpFlags is NULL, or if lpNumberOfBytesRecvd is NULL when  lpOverlapped is NULL.Also, the Parameters section for lpBuffers could mention that it is safe to point lpBuffers to a transient area of memory, such as the stack. Although this is stated in the Remarks section, a repetition would help clear some confusion for users."

In my case lpOverlapped is not NULL, but I can leave it unitialized, to get WSAEfault or initialize the .hEvent part to get (WSAEfault) or ("the handle value is invalid")


Thanks



edike123

I finally found the error!  :bg :bg

It was not related to anything I mentioned previously.
The problem was that I didn't know that after accepting an incoming client, I have to use setsockopt like this:

invoke setsockopt, temp_socket, IPPROTO_TCP, TCP_NODELAY, addr ch_sockopt, sizeof byte


The new error message from WSARecv is just what I wanted:  WSARecv - Overlapped I/O operation is in progress.