Skip to main content
gamedev.net
🔒 Locked

Most efficient server method?

Started by HopeDagger Jun 26, 2004 at 10:12 PM 2 replies 1k views
Original Post
HopeDagger
HopeDagger
For a game that I am currently developing (or rather, *planning* on developing!) I require a server that will need to support 50+ users at once, and be as fast as possible. I'm using the UDP/IP protocol, but I'm not sure what the best approach would be? Blocking sockets with select()? Non-blocking? I have no idea. What would be the most efficient method to pursue when dealing with a high volume of users? Thanks! [Edited by - HopeDagger on June 26, 2004 10:59:00 PM]
LordKaT
LordKaT
non-blocking is almost required nowadays. Especially for games.

I would read everything on multiplayer here on gamedev, and I would also read beej's guide to nework programming at http://www.ecst.csuchico.edu/~beej/guide/net/
cbenoi1
cbenoi1
Here is source code to a IOCP-based UDP network core. IOCP is the most efficient networking method on Win32 for a very large number of connections. But that's a solution that would work on NT/2K/XP class machines only.

http://pages.infinit.net/cbenoi1/iocp_udp.zip

If you are looking for a broader set of solutions, including cross-platforms, take a look here:

http://www.kegel.com/c10k.html
http://tangentsoft.net/wskfaq/articles/io-strategies.html

Hope this helps.

-cb
hplus0603
hplus0603
You can use select() without blocking in the select(). And you can use non-blocking sockets with select(). In fact, that's often better, because select() tells you you can read at least one byte without blocking; it doesn't tell you how much you can actually read.

If you're using UDP, you only need a single socket on the server, and you can use recvfrom() and sendto() to separate the different clients. This is most efficient. You can still select() on this socket. Also, if you're using UDP and select(), you don't need to make the socket non-blocking, because select() tells you that at least one call to recvfrom() will succeed without blocking.

If you run server physics at some fixed rate (good idea!) then your loop looks something like:

Time lastStep = Now();while( true ) {  RunAPhysicsStep();  Time then = lastStep + PhysicsStepSize;  while( true ) {    now = Now();    timeout = then-now;    if( timeout < 0 ) timeout = 0;    select( ...., timeout );    ServiceSocket( .... );    if( timeout <= 0 ) {      break;    }  }  lastStep = then;}


You might want to add some safe-guards, in case your physics step takes longer than real time. However, the loop, as written, will degrade to running as fast as it can at that point, with at least one call to service networks per physics step.

If you make your socket non-blocking, you can read as many datagrams as there are inside ServiceSocket(), until no more are in the queue; that's most efficient. If it's blocking, you can only (safely) read one, and have to go back through the loop again to get the next; slightly less efficient.
enum Bool { True, False, FileNotFound };

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.