• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2979
  • Last Modified:

Using WSAEventSelect and WSAWaitForMultipleEvents

I am a server. I need to accept many connections. I want to accept a connection, start servicing it and loop back up and repeat.

I have used the following logic but it does not seem to work as intended.

WSAStartup(0x202, &wsaData);
listenSocket = WSASocket(AF_INET, DEFAULT_PROTO, 0, NULL, 0, dwFlags);
bind(listenSocket, (struct sockaddr*)&local, sizeof(local);
listen(listenSocket, SOMAXCONN);
eventObject  = WSACreateEvent();
WSAEventSelect( listenSocket, eventObject, FD_ACCEPT );
for (;;)
{
    WSAWaitForMultipleEvents( 1, &eventObject, FALSE, WSA_INFINITE, FALSE );
    socket = WSAAccept(listenSocket, (struct sockaddr *)&from, &fromlen, conditionFunc, 0); // conditionFunc returns CF_ACCEPT
    .... process socket here ....
}
0
ESQuicksall
Asked:
ESQuicksall
  • 12
  • 2
1 Solution
 
ESQuicksallAuthor Commented:
I failed to say what happens ---

The WSAWaitForMultipleEvents sometimes does not seem to wait. When I call WSAAccept, the socket is -1 and WSAGetNextError is 10035 (A non-blocking socket operation could not be completed immediately). If I put a breakpoint on WSAWaitForMultipleEvents, the WSAAccept usually (but not always) returns a good socket.
0
 
AlexFMCommented:
WSANETWORKEVENTS events;
WSAStartup(0x202, &wsaData);
listenSocket = WSASocket(AF_INET, DEFAULT_PROTO, 0, NULL, 0, dwFlags);
bind(listenSocket, (struct sockaddr*)&local, sizeof(local);
eventObject  = WSACreateEvent();
WSAEventSelect( listenSocket, eventObject, FD_ACCEPT );
for (;;)
{
    if ( WSAWaitForMultipleEvents( 1, &eventObject, FALSE, WSA_INFINITE, FALSE ) == WAIT_OBJECT_0 )
    {
         DWORD dwResult = WSAEnumNetworkEvents(listenSocket , eventObject, &events);

         if ( events.lNetworkEvents & FD_ACCEPT )
         {
               socket = WSAAccept(listenSocket, (struct sockaddr *)&from, &fromlen, conditionFunc, 0);
               ...
         }
    }
    else
    {
        // error handling, break
    }
}



0
 
ESQuicksallAuthor Commented:
First, I assume you also want me to add the listen between the bind and the WSACreateEvent. I tried it without that and seems to be needed.

So I tried what you said but now WSAAccept returns 10014 "The system detected an invalid pointer address in attempting to use a pointer argument in a call".

Note that dwResult is a 0, listenSocket is a 0x7a0, eventObject is 0x784 and events.lNetworkEvents is 8.

from and fromLen are as follows:
    int                         fromlen;
    struct sockaddr_in  from;

I have seen this error in the past when all pointers are correct. I think there is an error but I think WSASockets reports it incorrectly. I just don't know where the error is.

At least you have agreed that I understand the usage of the functions (yours and mine are very similar).

Eddy
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
ESQuicksallAuthor Commented:
Your code and mine are basically the same because I have only one object. Since yours gave the strange 10014, I went back to mine which was giving the 10035.

I added WSAResetEvent( &eventObject ) to my code after the WSAAccept and got by the 10035 that it was producing. But now when I do the WSARecv (which is basically where I had the ...'s) I never get the callback which should happen due to the data that is received. I used Ethereal to verify that I am getting the data.

So the code is now like this:

WSAStartup(0x202, &wsaData);
listenSocket = WSASocket(AF_INET, DEFAULT_PROTO, 0, NULL, 0, dwFlags);
bind(listenSocket, (struct sockaddr*)&local, sizeof(local);
listen(listenSocket, SOMAXCONN);
eventObject  = WSACreateEvent();
WSAEventSelect( listenSocket, eventObject, FD_ACCEPT );
for (;;)
{
    WSAWaitForMultipleEvents( 1, &eventObject, FALSE, WSA_INFINITE, FALSE );
    socket = WSAAccept(listenSocket, (struct sockaddr *)&from, &fromlen, conditionFunc, 0); // conditionFunc returns CF_ACCEPT
    WSAResetEvent( &eventObject );
    WSARecv(,,,,,, TOEHW_RecvComplete);
   // a call to TOEHW_RecvComplete should occur after calling WSAWaitForMultipleEvents when it blocks
}

Note that the basic code has been working for a very long time. This is the old code:

WSAStartup(0x202, &wsaData);
listenSocket = WSASocket(AF_INET, DEFAULT_PROTO, 0, NULL, 0, dwFlags);
bind(listenSocket, (struct sockaddr*)&local, sizeof(local);
listen(listenSocket, SOMAXCONN);
for (;;)
{
    socket = WSAAccept(listenSocket, (struct sockaddr *)&from, &fromlen, conditionFunc, 0); // conditionFunc returns CF_ACCEPT
    WSARecv(,,,,,, TOEHW_RecvComplete);
   // a call to TOEHW_RecvComplete occurs after calling WSAAccept when it blocks
}




0
 
ESQuicksallAuthor Commented:
AlexFM, do you have any other ideas as to what is going on?

Eddy
0
 
ESQuicksallAuthor Commented:
Does anyone have any ideas as to what may be going on?
0
 
ESQuicksallAuthor Commented:
Does anyone know how I can raise the points on this? I really need an answer.
0
 
ESQuicksallAuthor Commented:
No correct answer has been given and my response has not been answered. I will be asking for a refund if there are no objections.

AlexFM, if I have misunderstood your comment, please let me know.

Eddy
0
 
ESQuicksallAuthor Commented:
DanRollins,

Can you please see if you know the answer to this or if you know someone that does?

Eddy
0
 
DanRollinsCommented:
Sorry, I do not know the answer.  You might get more response by asking in the C++ section.

Did you look at all previous answers containing "WSAWaitForMultipleEvents"?

   http://search.experts-exchange.com/search.jsp?query=WSAWaitForMultipleEvents

-- Dan
0
 
ESQuicksallAuthor Commented:

I may have found the problem with my original code. I forgot to set fromlen before I called WSAAccept:

    fromlen = sizeof(from)

I'll let you know if this works.

Eddy
0
 
ESQuicksallAuthor Commented:
It turns out that that bug correction did not help. So, I'm still stuck.
0
 
ESQuicksallAuthor Commented:
I got it working. I had three errors ...

(1) I had not set fromlen before the WSAAccept
(2) I had to call WSAResetEvent( &eventObject) as I mentioned above
(3) I had to set the last argument of  WSAWaitForMultipleEvents to TRUE.

Case 3 really had nothing to do with my problem. It had to do with the fact that I use WSARecv in non-blocking mode and if you don't set the last argument to TRUE, the lpCompletionROUTINE in WSARecv will not get called. When it does get called, WSAWaitForMultipleEvents will return with WAIT_IO_COMPLETION.

I'm giving AlexFM credit because he at least confirmed that I had the right idea which itself was very important to me.
0
 
ESQuicksallAuthor Commented:
So, here is the correct code:

WSAStartup(0x202, &wsaData);
listenSocket = WSASocket(AF_INET, DEFAULT_PROTO, 0, NULL, 0, dwFlags);
bind(listenSocket, (struct sockaddr*)&local, sizeof(local);
listen(listenSocket, SOMAXCONN);
eventObject  = WSACreateEvent();
WSAEventSelect( listenSocket, eventObject, FD_ACCEPT );
for (;;)
{
    do {
        rc = WSAWaitForMultipleEvents( 1, &eventObject, FALSE, WSA_INFINITE, TRUE );
    } while (rc != WAIT_IO_COMPLETION);
    fromlen = sizeof(from);
    socket = WSAAccept(listenSocket, (struct sockaddr *)&from, &fromlen, conditionFunc, 0); // conditionFunc returns CF_ACCEPT
    WSAResetEvent( &eventObject );
    WSARecv(,,,,,, TOEHW_RecvComplete);
   // a call to TOEHW_RecvComplete should occur after calling WSAWaitForMultipleEvents when it blocks
}
0
 
DanRollinsCommented:
ESQuicksall,
Thanks for finalizing this and providing such a good explanation of the solution you found. :-)
-- Dan
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 12
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now