Sign in to follow this  

network design

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

i know how sockets work, how the functions work etc.. i'm here to find out the best way i should set up a server for my online game. first i'll say that i made the game before in an interpreted language but it was slow, so i'm now making it in c++. that being said i know most of what i'm going to need, and hopefully you'll be able to tell me the best techniques to use to go about programming my server. the server sends everything tcp (even movement, trust me the way i do it is almost as fast as udp). the server doesn't do a whole lot of work besides query from a database, and control movement. it does control mobs' ai, but the ai executes fast; there really isn't much to it. the packets that the server send are usually fairly small, about 10-50 bytes worth of data. the movement packets however are fairly large, about 50-500 bytes worth of data. finally the server usually serves about 5-20 people at a time. i was thinking of just having an array of sockets and doing all the networking in one thread, doing all the querying in another thread, and everything else in the main thread. i don't really know a whole lot about multithreading, i'm still learning, so i don't know if thats the best way to go or not. what do you think? thank you for your time.

Share this post


Link to post
Share on other sites
Hi,
That actually is really a matter of taste! I do not like threads, here is how I would do it.
Set up your sockets. Than, in the main loop do something like:

while(running)
{
DoOtherStuff();
if(DataWaiting())
GetAndProcessData();
}

You can check if data is waiting in your sockets using select. You you want your application to do nothing until data is coming, you can also give select a timeout value.

As I said, other prefer threads. It is a matter of opinion. I prefer this way because I find it to be less complicated.

Nathan

Share this post


Link to post
Share on other sites
If a movement packet is 500 bytes, and you have 20 clients, then the movement data for 20 clients (assuming one packet/second) is 10 kilobytes per client -- times 20! Meaning you need 200 kilobytes (about 2000 kilobits with framing) per second of upstream bandwidth from the server.

I would let the kernel buffer the data, and do a single-threaded server, much like LonelyStar suggests.


while( running ) {
select()
read from all ready sockets
process messages from those sockets
run one simulation step
write to all sockets that have data pending
}


The kernel will buffer before the read, and the stuff in write, so it'll actually receive/send the network messages asynchronously from you issuing the calls.

Note that you usually have to worry about the output buffer filling up, and the write blocking, unless you select() for write or use non-blocking sockets, and do your own queuing.

Share this post


Link to post
Share on other sites
the movement packet is 10 bytes per charecter within a set distance of the player. there are usually only about 5-10 characters within the set distance, but when a player is in a crowded area with lots of npc it can get out of hand. the movement packet for 20 players usually only takes 12-20kb bandwidth per second. its not that out of hand.

anyways, i've read in several threads that a thread for the network is the way to go. but it seems like here you have a different oppinion. what are my advantages and disadvantages for using a thread for networking? i thought it was suppose to be much faster using a thread for networking, but i guess i could be wrong.

Share this post


Link to post
Share on other sites
If you have a second CPU sitting around doing nothing, and a good mechanism of handing off data between the processing thread and the networking thread, then the networking thread may give you some additional performance (because of the CPU parallelism), at the cost of synchronization and context switching (cache thrashing).

If you have a single CPU, don't worry about threads, because there's only one piece of hardware doing the work.

Share this post


Link to post
Share on other sites

recommend a multi-threaded pool approach with appropriate dispatcher to handle tasks.

Would suggest using async sockets with a hidden window for receiving messages or overlapped io.

As for network speed , the problem with TCP is that TCP windows cause real-time networking delays. If you have TCP up and running you can always modify it to use UDP at a latter stage.

good luck
Cubex

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I agree with hplus. Either use a signle thread for everything, or if you have 2 processors, or a hyperthreading processor then do a thread for the network, and a thread for the game.

Your network card and IP stack will work asynchronously from the process your game is running in. Odds are, the game itself is only going to process input once in it's loop, and send output back to the network once in it's loop. So having 2 threads really doesn't save you much latency. (It could save you the time it takes to read data from a socket, because that would be happening at the same time the game loop is running), but thats really not a very large chunk of time.

I do not think you will gain anything by having a thread pool for network. Threads work well when one thread stops doing something for a while, and gives the other threads time to process. So it would go somewhat like this:

Thread 1:

anything on socket 1? nope? ok.. sleep;
Thread 2 starts processing

Thread 2:
anything on socket 2? yep? ok, read from socket.. sleep;

Thread3:
anything on socket 3?
... etc..

you get the point.. There is no real point in having more threads than the processor can simultaneously handle. if the processor is single core, doing a select() and then cycling through your fd list is probably FASTER than dealing with the context switch and thread safe mechanisms of the threaded version.


Single threaded model:

Check to see which sockets have data waiting.

for each socket:

is there data waiting? yes? read. no? continue;


Threads are neat concepts, but I see them being abused so much. As hardware moves to be more multicore, and suports multiple native threads, then these models will be much more practical, but you still don't want to have more threads than your hardware can natively support.





If you use blocking calls, and select(), you will get the same responsiveness as asynchronous sockets, but without the added headache that is associated with them.

Share this post


Link to post
Share on other sites
Yes I agree, that single threaded with select is a pretty good way to go. Not only does it work perfectly well and as the other said even with two cpu it's doubtful wether or not you'll see improvements but you have to consider how much more simple the logic is going to be. Multiple threads can be quite a headache. Also, we do have a dual processor machine but we're using the second cpu to do more useful things like running a part of the simulation or handling incremental saves.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Threads are neat concepts, but I see them being abused so much. As hardware moves to be more multicore, and suports multiple native threads, then these models will be much more practical, but you still don't want to have more threads than your hardware can natively support.


Why are multicore CPU's justification for writing multithreaded applications as opposed to the multiple cpu servers we've had for ages?

-=[ Megahertz ]=-

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Multicore seems to be the current trend. Mhz speeds are reaching a plateau, and in order to maintain the current processing speed increases, multicore designs are going to become more and more prevalent.

There is no difference between multi cpu and multicore as far as my points were concerned, other than the fact that the new multi cpu systems will feature multicore processors as well. right now if you have a 2 cpu system with single core chips you have 2 hardware threads. In a 2 cpu system with 3 core cpus you have 6 hardware threads. The possibilities for more efficiently utilizing larger number of threads for mainstream apps is on the horizon. I'm just not sure than using a pool of these threads for networking would be as efficient as using them for physics, or other more computationally bound systems.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you are going for the single thread solution (keep option open to go multi if it doesnt perform fast enuf...), you should look into the TCP interface commands for maximizing/increasing its buffers.

Another trick (I used for DOS games to poll input more frequently that the game cycle) was to call the network get/post packet routines more than once per cycle (intersperse a call in more than one point in the game loop) and transfer the data to program buffers (and maybe prefilter) -- thus keeping too much from piling up in the TCP buffer.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

My current game loop:
-repeat N times:
-packet = nonblocking udp recv
-if packet == NULL: exit loop
-process packet (store commands)
-get time
-if time tick elapsed:
-foreach session:
-step simulation
-foreach session:
-rule checks
-foreach session:
-packet = asseble packet
-nonblocking udp send (packet)


The input and output buffering is done by the kernel, because I set up large input/output buffers for the udp packets. (with standard ioctls) The game logic is the same as in a single user game with multiple players sharing a keyboard. The network logic is a single recv keys and text/send positions and text, and any prediction code (dead deckoning) is in the clients.

Viktor

Share this post


Link to post
Share on other sites

This topic is 4350 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this