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.
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.
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
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.