🎉 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!

blocking or non-blocking

Started by
31 comments, last by wrathgame 22 years, 10 months ago
Hi, Im sure this is a common subject.. but whats the behefits of using blocking or non-blacking for a game server? im currently using threaded blocking.. would there be any advantage using non-blocking ??? i cant see how there could my self but i though i would check thanks -Tim Also .. is it a really bad idea to have non-blocking client and blocking (threaded) server or does it make no difference ? thanks -Tim Edited by - wrathgame on August 15, 2001 10:36:46 AM
~ Tim
Advertisement
First of all, the server doesn''t have to worry about whether the client is using blocking or non-blocking and vice versa. It doesn''t matter at all, and you can have any mix you want.

Basically, if you''ve got a threaded or multi-process layout (with one thread/process per connection), blocking will be just fine.

Otherwise (i.e. all connections are handled by a single thread), you have to be careful about what you''re doing, as a blocking call on a dead connection will cause major lag (effectively, the game will stop for some minutes...).

Now, if you''re all careful, using select() and everything, to make sure there''s always data available when you call recv(), you won''t get into trouble with blocking sockets either.
However, be aware that send() calls might also block when the OS buffers get full. So you either have to check whether a socket is prepared for sends (you can do all the checks in one go with select()), or use non-blocking sockets instead.

cu,
Prefect

One line of sourcecode says more than a thousand words.
Widelands - laid back, free software strategy
Thanks ;-)

ill stick with my current combination then

-tim
~ Tim
Servers in general should use non-blocking operations (overlapped i/o) in order to maximize memory and thread usage. Having one thread per connection on a server, under Windows, is just *bad* and not recommended.

Unfortunately, the select() function call is a polling mechanism that returns sockets that have met a certain criteria. You need to continually call select() to find sockets that have completed their operations. Not a good solution for an efficient server.

Clients, on the other hand, can typically use blocking operations because they are working on a 1 to 1 relationship. The client connects to one server. The thread per connection model can work on the client side but it still suffers when connection counts increase. Still, a game client can get away with blocking operations or non-blocking with select().

What exactly are you trying to accomplish?

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

well i read (and tried and tested this) that u can only have about 64 connections per thread using winsock (note : im using win 2000) at which point it refuses to accept any more so i started using 1/thread which lets me have a LOT of connections .. basically in win 2K its limited to my RAM :-)

so you think its a really bad thing to have 1 thread per blocking socket hmmm what other options do u surjest ? non blocking and say 60 connections per thread.. that will be a job to change to but if its worth it i will ? the server at the moment (admitedly only had about 7 max) runs at < 1% cpu (says 0% usually) so doesnt seem too intensive

thanks for any advice

-Tim
~ Tim
A maximum of 64 connections per thread? Where did you read that? I think you might be confusing that limitation with the number of event handles that can be passed to WSAWaitForMultipleEvents (64 handles).

I''ve written server software using I/O completion ports under Windows 2000 that can handle approximately 20,000 connections per *second* on a 4x P3-800 with 2 gigs of RAM.

I further know a programmer from Microsoft who wrote a server service that handled over 100,000 connections per *second* using I/O completion ports.

With I/O completion ports you typically have 2 threads per processor and set the concurrency limit to the number of processors. So on a 4x CPU machine that is 8 threads in total servicing over 20K connections. That works out to 2,500 connections per second per thread. Given the way I/O completion ports work it is possible that only 4 threads may be running at any given time on a 4x CPU system.

Under Windows, the limitation is not directly your RAM. The limitation resides in the amount of non-paged memory . This is typically 1/4 of your RAM (I think Windows 2000 increases that to 1/2). I can''t remember how much non-paged RAM each socket takes up but you have to be careful.

Another problem with the per-thread model is the problem of thread context switching. If you have 1000 connections you will have 1000 threads or in your case approximately 15 threads. This means on a uni-processor system Windows will need to make 15 thread context switches and that is not taking into consideration other programs that may be running at the time.

Now you are only talking about 7 connections so admittedly you are probably not really noticing any major performance issues

The most efficient servers use I/O completion ports and overlapped I/O.

Hope this helps,






Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
thanks for all the help...

does anyone have a clue where i can find out about iocp ? especially in my prefered language (Delphi) but anything is better than nothing ;-) i have looked and i havent found anything decent yet

thanks

-Tim
~ Tim
Can Delphi make calls to the native Win32 API in code?

Do you have the Microsoft Platform SDK handy? You can look it up in there.

Start by looking up:

CreateIoCompletionPort
GetQueuedCompletionStatus
PostQueuedCompletionStatus

Best regards,





Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Umm... what is this about select() being bad? I mean, what are the other options?

If you''ve got a waiting server, i.e. most typical internet servers (think IRC for this purpose), you''d be doing idle loops if it weren''t for select().

If you''re in an environment where you''re doing busy loops anyway (think game servers), you might think select() is not needed. However, think about this:
You''ve got a server with 40 clients, running in busy-loop at 100fps (which is low if the server doesn''t need to display graphics). Every client sends 20 packets per second. In other words, on average you need to read 8 incoming packets per second.

Now if you use one select() call (timeout set to 0), you end up having 9 system calls per frame (one for the select() and 8 recvfrom()s).
If you just blindly receive from all the sockets without select()ing or poll()ing first, you need 40 systemcalls.

Now judge for yourself...

I''m not sure about the select() platform on all systems. Ideally, they should catch 0 timeouts and not suspend the process. If they do... *sigh* slap the OS programmers and look for alternatives.

Reducing OS calls can really help a lot.

cu,
Prefect

One line of sourcecode says more than a thousand words.
Widelands - laid back, free software strategy
and select() is somewhat more portable...

WinSock has(had?) a max 64 sockets by DEFAULT. I don''t think it is a per thread basis; I think it was all the TCP/IP stack was setup for by default. I do know you can change it somewhere in system settings (I forget where). Not too sure about the newer Windoze versions, but this holds true on <= win98se. I''m doing UNIX stuff lately, so I''ll refrain from giving outdated and/or inaccurate info on M$ stuff.

Tim/Fingh

This topic is closed to new replies.

Advertisement