Jump to content
  • Advertisement
Sign in to follow this  

WSAEWOULDBLOCK with Asynchronous sockets

This topic is 4338 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When using asynchronous sockets, I get errors when I try and call recv(). Using WSAGetLastError(), I get a result of WSAEWOULDBLOCK. Now I understand that this is perfectly natural for asynchronous sockets. However, I only call recv() when in the Windows Proc() function, when a WM_SOCKET (my custom socket message sent to WSAAsyncSelect()) fires with the FD_READ parameter. In other words, I am only calling recv when the socket should be ready to receive data (and thus shouldn't return an error of WSAEWOULDBLOCK). What causes this to occur? And what is the proper way to deal with it? Thanks. -Gauvir_Mucca

Share this post


Link to post
Share on other sites
Advertisement
Ok, so I keep calling recv() until either I get an error that is not WSAEWOULDBLOCK or until I sucessfully read in the data that is being sent.

This just results in an infinite loop. My socket is constantly in a position where calling recv() would block. What would cause this?

Share this post


Link to post
Share on other sites
If there is no data, there will be no data to read. Maybe someone else read it, or maybe some other socket has the data (i e, a bug in your handling of WM_SOCKET/WSAAsyncSelect()), or something else along those lines.

Btw: async sockets is Windows specific, and is not high performance. You're likely better off teaching yourself regular select() socket programming, or (for highest performance on Windows) IOCP with sockets.

Share this post


Link to post
Share on other sites
I agree that windows async sockets is not the way to go, either from performance (hijacks the user32 message system for something not involving the UI), or platform compatibility.

However, if you're writing a game which has a loop which spins frequently anyway, you could do worse than poll your sockets inside this loop. After all, there is no need to read data more frequently than your code will use it.

If you're writing a server application (i.e. without a permanently spinning game loop), then you should of course consider using "proper" select / asynch techniques.

From what I understand**, asynch IO is advocated on win32 because select() isn't terribly scalable to large numbers of sockets. If you only have a few, you should be fine.

Mark

** This is perceived wisdom and hence should not be taken as Gospel Truth :)

Share this post


Link to post
Share on other sites
In answer to your original question, you should probably ignore it.

WSAAsyncSelect, *I think* POSTs messages to your app's message queue. It will only post ONE message per socket per recv (for reading anyway). Therefore any more data which arrive afterwards will not generate more messages.

It's entirely possible that you've already consumed the data that the message was referring to, in which case yes, you'll get EWOULDBLOCK. It is safe to ignore this, as after you get EWOULDBLOCK, WSAAsyncSelect automatically re-primes itself and will send a new message as soon as anything new arrives.

Mark

Share this post


Link to post
Share on other sites
Note that there's a difference between asynchronous sockets (as done by Winsock) and non-blocking sockets. Berkeley-compatible sockets (which exist on basically every relevant OS out there) provide non-blocking modes - read and write will return the result EAGAIN instead of WSAEWOULDBLOCK. Non-blocking sockets are typically natively implemented at the kernel level (in *nix world) or a very low level indeed (possibly kernel, not sure about Windows). Native non-blocking sockets are fine for performance provided you're not trying to write a server that handles more than 5-10 concurrent incoming connections, and even then you can get away with quite a lot in reality. Since any Berkeley-compatible socket implementation will support them, there's also no portability concern.

By contrast, async sockets do some evil garbage with the Win32 message pump (as markr noted) and they are generally a Bad Thing. Personally, I prefer to not use Winsock's API directly at all (unless I need IOCP for a high-performance server) and instead just use the Berkeley functions directly. They map straight to Winsock on Windows anyways, and that way I know the functions already on any major platform.


In any case, before you rip out all your socket code for performance, at least double-check that you are in fact having performance problems (but do rip out your async socket code anyways, since it's evil). I've written some realtime network traffic processing tools using Winsock's non-blocking socket modes and had absolutely no problems, even on low-end hardware (think PIII 433 machines) so it's not like you have to run out and become an IOCP wizard to keep your code from chugging along [smile]

Share this post


Link to post
Share on other sites
Quote:
asynch IO is advocated on win32 because select() isn't terribly scalable to large numbers of sockets


The performance of async sockets on win32 is terrible, and has a hard limit at 64 sockets to boot. select() on windows usually performs better, and can go to more sockets with the appropriate #define before including winsock2.h.

You may be confusing it with I/O Completion Ports, which use separate worker threads to complete overlapped I/O requests on sockets. That's the highest-performance path on Windows, but is very platform specific.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!