[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Using WSAEventSelect and WSAWaitForMultipleEvents

Posted on 2004-10-30
16
Medium Priority
?
2,776 Views
Last Modified: 2013-12-03
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
Comment
Question by:ESQuicksall
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 12
  • 2
16 Comments
 

Author Comment

by:ESQuicksall
ID: 12454204
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
 
LVL 48

Accepted Solution

by:
AlexFM earned 2000 total points
ID: 12455897
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
 

Author Comment

by:ESQuicksall
ID: 12457889
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
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 

Author Comment

by:ESQuicksall
ID: 12458143
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
 

Author Comment

by:ESQuicksall
ID: 12472148
AlexFM, do you have any other ideas as to what is going on?

Eddy
0
 

Author Comment

by:ESQuicksall
ID: 12523705
Does anyone have any ideas as to what may be going on?
0
 

Author Comment

by:ESQuicksall
ID: 12545431
Does anyone know how I can raise the points on this? I really need an answer.
0
 

Author Comment

by:ESQuicksall
ID: 12818938
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
 

Author Comment

by:ESQuicksall
ID: 12863085
DanRollins,

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

Eddy
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 12864901
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
 

Author Comment

by:ESQuicksall
ID: 12878790

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
 

Author Comment

by:ESQuicksall
ID: 12880131
It turns out that that bug correction did not help. So, I'm still stuck.
0
 

Author Comment

by:ESQuicksall
ID: 12896148
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
 

Author Comment

by:ESQuicksall
ID: 12896192
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 13027152
ESQuicksall,
Thanks for finalizing this and providing such a good explanation of the solution you found. :-)
-- Dan
0

Featured Post

NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question