🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

WSAEventSelect

Started by
14 comments, last by Shannon Barber 22 years, 5 months ago
Ok, I have this crazy idea of handling of handling all my network communications asyncronsouly using one (user mode) thread dedicated to the task. In order to do this, I need to receive connection and close event notifications; since the overlapped version of Connect is only available on XP, I think the only way to have an event signaled upon connection completion is using WSAEventSelect - it''s also the only way I see to receive a close event as well. I fool-heartily tried to call WSAEventSelect twice, once setting up an event for close, and again for connect. It only remembers the last call - so it seems you can only have one event be signaled for anything you want to watch. So, my question is, once that event is signaled, how do I tell if it was signaled because the socket was closed, or because it was connected? (without adversely affecting the potentially connected socket)
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Advertisement
Been awhile since i did this but it goes something like this
wsaSelectEvent (..., CLOSE | CONNECT);


no no no, I know how to use WSAEventSelect - the problem is when you give it multiple conditions to signal upon, they all signal the same event.

What happens if the socket connects and is closed before my thread is awoken to handle the connect event?

if(SOCKET_ERROR==WSAEventSelect(m_socket, m_evConnectOrClose, FD_CLOSE|FD_CONNECT)) 


I think I can just issue an overlapped receive request, and if it succeeds I can conclude the event triggered because the socket connected, and if it fails I can conclude the socket is closed. I guess I can keep a crappy flag around that indicates whether or not I''m expecting a connection event. That way when the event is signal by the close conditions, due to an aborted connection, I know to clean-up...
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
argh, what if the connection fails?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
If the socket connects and is then closed, you''ll receive an FD_CONNECT first and an FD_CLOSE later. Do some error checking on the socket during FD_CONNECT to see if it''s still valid. Connection failure == FD_CLOSE.
________________________________________________"Optimal decisions, once made, do not need to be changed." - Robert Sedgewick, Algorithms in C
I''m also working on my nework thread/subsystem at the moment..

What I did was go through the listen/connection procedure with blocking calls (since this is all happening in its own thread) then once the connection is established use WSAEventSelect with FD_CLOSE | FD_READ...

According to MSDN recv will return 0 if the connection was gracefully closed, the number of bytes read if there was data, and SOCKET_ERROR for everything else... No say about if there was no data.. but by using that I figured I could determine if the event was FD_CLOSE of FD_READ..

Of course, once my thread moves to the wait_for_data state WaitForSingleObject returns immediately, and recv has a return value of 0, indicating that the connection was closed. All of this occurs immediately after i had just sent data verifying protocol version... Still can''t seem to track down what is causing the connection to close....
I''m going to use IOCP or overlapped IO for sending and receiving data, so that works fine. And the server is running on NT, so I''m using AcceptEx with no (serious) problems.

I''m trying to get asyncronous connections and close notifications working - maybe the best way to do it, is to register and create a bogus window and have it send messages to it''s queue - I think there''s a wait function that waits on events and a window message queue...

Right now I don''t get any messages, as I use EventSelect not the one for messages.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Another way you can do it is to write your own Asynchronous Method implementation. Create a Command object that has a pure virtual execute() method. Create another class named AsyncConnect and subclass from the Command object. AsyncConnect''s constructor will take whatever parameters you need and store them in internal private data. Then create an instance of AsyncConnect, when needed, and send it to an AsyncScheduler (basically a fancy list/vector/queue.) When the AsyncScheduler receives the AsyncConnect object, it posts a completion token to the I/O completion port. One of the threads from the port wakes up, realizes that it needs to contact the AsyncScheduler. The thread servicing the IOCP notification then calls the process() command on the AsyncScheduler. The AsyncScheduler dequeues the AsyncConnect and calls its execute() method. The AsyncScheduler''s execute() method then calls connect() (in a different thread from the client.)

The tricky part is getting the result back to the client. The client needs to know when to check the result. This can be accomplished by either what is known as "Futures." The other alternative is to use callback events. Callbacks are more immediate but it becomes a challenge to control which thread issues the callback. You can build an event/callback thread manager but it depends on how far you want to go. The I/O completion server I wrote for a client uses event callbacks from the I/O completion service threads.

Wheeeeeeww!!

I know the coding overhead sounds brutal but Asynchronous Methods are a powerful technique. The implementation I developed is a slight variation on the ACE Framework''s Active Object design pattern.

Enough typing for me...



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
That's the path I'm going down - I've created a thread to establish connections on, and I'll have it signal an event for the overlapped mode, and I'll look into queuing a CP when I get to that.

The problem is, I now have a non-blocking/overlapped socket, but I now want a blocking connection... The connect method returns immdiately, and I still don't have a way to determine when/if the sock - ahhhhh I'll just keep calling connect, and it'll return WSAEISCONN once the connection is established. Not beautiful, but it'll work for now, and someday I can switch it to use a real overlapped technique easily.

Edited by - Magmai Kai Holmlor on January 19, 2002 6:49:33 PM
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Yeah once Windows XP is THE standard.

Can''t believe MS never implemented a ConnectEx type API. What an oversight.

Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com

This topic is closed to new replies.

Advertisement