Experiences with non-blocking vs asynchronous sockets?

Started by
12 comments, last by MatrixCubed 21 years, 10 months ago
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
Advertisement
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
Winsock programming requires that you experiment. Try different Winsock application models and see what works best for the program you are working on.

Kuphryn
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>.
- 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
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.

-------------Ban KalvinB !
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.
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]
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]
------GameDev'er 4 ever.
Messy ? Why ?
-------------Ban KalvinB !
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

This topic is closed to new replies.

Advertisement