Archived

This topic is now archived and is closed to further replies.

Experiences with non-blocking vs asynchronous sockets?

This topic is 5652 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

Hello, I''ve been reading up on non-blocking sockets, and I am interested to know what experiences, pitfalls/advantages you''ve come across, compared to asynch socket programming you might have done. I''ve always only used asynch or threaded/blocking sockets, and have not ever touched non-blocking style of application design. Comments? MatrixCubed
http://MatrixCubed.cjb.net

Share this post


Link to post
Share on other sites
i used non-blocking sockets once and i think it was a bad idea

basicakky what you do is continually call the function and you will recieve data or recieve an error saying there is no data or something like that. so every loop through your game or whatever you are making you must call the recieve(....) function every time. If there is no data to recieve then there is overhead in that function call which you really didnt need to call at all.
So if you were writing a game server for say several hundred gamers. That could potentially be several hundred extra function calls to recieve(....) when you didnt need to because there was no data to be read.

I personally prefer the blocking/threaded method.
Asynchronous is ok but i dont like all that stuff jumbled up in my message loop. And if you set up your main game loop like me
pseudocode

  
while (still playing game)
{
while (message to be handled)
{
handleMessage();
}
mainGameLoop();
}

then if you recieved 200 packets from connected clients
then it would have to run the message handler 200 times before your game loop could get executed again. That could lead to significant delays in the game.

If you use the blocking/threaded method then the mainGameLoop will be running while the messages are handled. Yes, i know they both wont be running at the exact same time because that is impossible unless you have multiple processors in your pc.....but the mainGameLoop wont have to wait for the 200 messages to be processed before it can start its execution.
Also.........be aware that you need to use sephamores or something similar to make sure that the threads only access shared memory one at a time or you can get some seriously messed up effects.



"I pity the fool, thug, or soul who tries to take over the world, then goes home crying to his momma."
- Mr. T

Share this post


Link to post
Share on other sites
Winsock programming requires that you experiment. Try different Winsock application models and see what works best for the program you are working on.

Kuphryn

Share this post


Link to post
Share on other sites
You can make a bogus (invisible) window to receive winsock notifations and run it in a seperate thread from the main message pump. Or use events and not bother with a message pump at all.

Asycronous sockets provide minimal latency, whereas non-blocking can provide high through-put with low CPU utilization - you can get the same performance from async, but you have to add a level of indirection that increases the latency. This is how DirectPlay6< works and it''s recommended that you implement a message queue and use worker threads to process those messages for DirectPlay8>.

Share this post


Link to post
Share on other sites
quote:
Original post by ncsu121978
So if you were writing a game server for say several hundred gamers. That could potentially be several hundred extra function calls to recieve(....) when you didnt need to because there was no data to be read.



If you use UDP and each client sends to the same port then you only have to "waste" one receive call each poll.
Not that bad.

Besides. I would rather waste one receive call than one thread switch.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I use a non-blocking socket to accept new connections, and then I open a socket for each client, which is blocking, and shuffle them off onto it.

Share this post


Link to post
Share on other sites
I have to agree with the post that non-blocking sockets aren't as nice as blocking ones. I have used both, unfortunately API's such as WON implement non-blocking socket objects which are overlaid ontop of the conventional berkley blocking sockets. Grr

This means your listen thread has to poll the listen port continuously whether there is a connection coming in or not, and check the return value each iteration to see if a new player was incoming. You might think to yourself, "eh so I eat a few hundred clock cycles per second, so what". But API's which have non-blocking accept calls for the listen server, probably are also using non-blocking receives as well. This is the biggest problem in my personal opinion. It implies you have a game in which you have been able to define a rate at which packets should be received that is optimal is all game situations. IE if youy poll then you must sleep between polls, this means you are locking yourself into a hard rate of which can delay your packet from being processed by the amount your sleep is. I can't think of many games that I play where 100ms guaranteed delay because of non-blocking sockets is ever going to be something I just "figure in" to my latency calculations.

In my opinion, non-blocking sockets are evil, and should only ever be used in an application in which a heartbeat is the only data you ever send, and/or latency of 100ms - 2000ms is not a concern at all.

I am sure there are benefits to be gained by non-blocking sockets or else why would they be there, but I haven't found them to be the best solution for anything I have worked on yet, however, my experience is limited to games, not applications.

That being said I typically use the following:
Threaded listen server (starts recv and send threads for this client)
Threaded receive (one per client) which accesses a MUX'd input queue
Threaded send which accesses a MUX'd outgoing queue (keeps app from having to delay for TCP send ack recv)

anyway, I hope this adds to the discussion.
--jeff "mother"

[edited by - jcurley on June 12, 2002 5:08:45 PM]

Share this post


Link to post
Share on other sites
I suggest you don't use non-blocking sockets because your code could become very messy.
It depends of the kind of online game you want to make but in most cases, asynchronous sockets are definitely the best choice for your server AND for your client. (Well that's my 2 cents).

And blocking/threaded sockets gives results comparable to asynchronous sockets. It is the same principle except asynchronous sockets recquire a WIN32 application.


------
GameDev'er 4 ever.


[edited by - Khelz on June 13, 2002 1:02:21 AM]

Share this post


Link to post
Share on other sites
Take a look at this article: Which I/O Strategy Should I Use?
It pretty much goes over most of socket handling models.

As for the one I prefer... I use non-blocking sockets, since I like having my servers'' portable. Asynchronous sockets are great, but only if you''re just building for Windows. As for using threads, you will notice significant slow down before you hit 100 simultaneous connections (unless they''re all idle).

However, you should just go with the system(s) you''re familiar with. Spending a whole bunch of time trying to get your game entirely efficient can cripple any chance you had of completing it.

Just my opinion.

-Ummno

Share this post


Link to post
Share on other sites
quote:
Original post by granat
Messy ? Why ?


Non-blocking sockets are almost never necessary, and a good thing, too: their lack of performance makes them a poor architecture choice.

When a socket is set as non-blocking, every Winsock call on that socket will return immediately, whether it was able to do anything or not. This is useful because it lets your program do other things while the network is busy. The problem is, sometimes the program doesn't have anything to do. This leads to a commonly-seen construct that might be called "spin until the network becomes ready".

About the only time you should use non-blocking sockets and/or select() is when you are porting BSD sockets code to Winsock or when your code must also work under BSD sockets. In all other cases, there are better alternatives.





------
GameDev'er 4 ever.

[edited by - Khelz on June 21, 2002 9:42:39 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
"a poor architecture choice." could lead to a messy code.

Share this post


Link to post
Share on other sites
If you''re running in a busy loop anyway there''s nothing wrong with using non-blocking sockets. And remember, games typically run in a busy loop (game servers are a different thing of course).

Now you could of course implement a blocking/threaded or asynchronous (win32 only) system even in the client. However, due to locking and stuff, you usually won''t be able to process incoming packets immediately anyway, so the benefits are questionable - you have to wait until rendering is finished, for example.
Now if you timestamp incoming packets by using a threaded/asynchronous system and make good use of those timestamps it may be worth it.

Personally, I use non-blocking in the client (which busy loops anyway), and blocking/non-threaded in the server (because that''s portable).

cu,
Prefect

Return to the Shadows

Share this post


Link to post
Share on other sites