3

I am studying the structure for my server-client communications in my multiplayer game.

I came to the conclusion that UDP is the best choice due to the "shoot and forget" way of using it that will not block the application if a packet is lost. I will also use TCP to send reliability needing packets, like during login procedures and exchange of informations like change of server, change of map, updates etc. It will also run an IRC based chat. (all the commands actually are IRC-style custom messages).

I was wondering what is the best way to send the interaction messages (moves, spells, objects, actions etc) between server and clients.

Reading some documentation I came to the MulticastSocket.

My question is:

Is better to send a continuous flow of information to all the clients starting a thread for each player (as I do in TCP communications) where each DatagramSockets will listen to a queue sending each new message to its client. This will mean that all the maps and all the movements (supposing there can be 50 players all-over the maps) will be sent to all the players, and each packet has to be larger to contain all those informations. Or is better to use a thread for each map, active only if some player are inside that specific map, using a multicast communication, sending a message to only the players that are inside that map, listening with a MulticastSocket.

I read about problems with firewall or routers using multicast, but I can't figure out what those problems can be (different from normal UDP).

The application should be used by anyone with few configuration problems.

Gianmarco
  • 2,536
  • 25
  • 57
  • Some routers are configured to block multicast packets as they can cause unwanted traffic on a network. Just imagine a malicious user spamming dummy multicast packets all over the network with wildcard addresses. The scope of the packets also matter. Packets are less likely to reach if they are on a bigger network (e.g the internet) compared to smaller networks like a private LAN. As to whether this can be avoided (while still using multicast), I cannot give you a good answer. – initramfs Aug 25 '13 at 16:09
  • I am not sticked with multicast, in fact the question is about what is the best way to create the communication server-clients with UDP and I can change with no problem. Maybe I can create a class that emulate a multicast socket, sending the same packet to multiple clients at once? But I don't know if it will be fast enough. Thank you for your comment – Gianmarco Aug 25 '13 at 16:34
  • I'd be more concerned over bandwidth than speed. A multicast packet is sent once compared to a traditional network structure that requires a packet per connection. If 50 players are in the server, you must consider 50x bandwidth compared to a single connected user. I was only offering my insights on multi-cast packets. – initramfs Aug 25 '13 at 16:39
  • Responding to your general question. I personalty think it would much cleaner and modular if you handled one thread per player. It would definitely be faster in terms of networking but you have to think about the overhead caused by synchronization. You've described the possibility of having 50 players, now a single thread can handle that with a slight network lag or you can have 50 threads with little network lag but high resource usage. Its up to you whether network performance should gain priority – initramfs Aug 25 '13 at 16:48
  • I have not clear what can be the structure for a single thread connection, but i cannot also understand why you tell me that a single thread per player (and this mean a socket for each player) is faster. I was going for one thread for player, but I never thought about what sync problem I can have. Again thanks for your comments – Gianmarco Aug 25 '13 at 16:54
  • One thread per player means player data can be processed concurrently in a parallel fashion. For example, if data comes in regarding a player getting hit, each thread can handle things like reducing health independently (i.e Processing time is O(1) regardless of number of players) vs O(n) with a single thread. The problem comes when many many player threads want to access the same resource at once, synchronization is generally very slow. – initramfs Aug 25 '13 at 17:26
  • Now, you WILL need to create 1 thread per connection anyway (since DatagramSocket.recieve() blocks (unless you are using nio)). My point is, if you are creating 1 thread per connection, why not port some of the processing code onto the thread itself to allow concurrent operation. – initramfs Aug 25 '13 at 17:29
  • thank you, you give me many ideas, why not try to put them in an answer, receiving my vote up? – Gianmarco Aug 25 '13 at 21:56

1 Answers1

3

Looking at your scenario above you need to decided if your application absolutely needs TCP connection as TCP connection requires one thread per TCP connection, no exceptions (unless using nio).

Now to target the UDP section of the program, you have two basic choices:

a) You spawn one thread for receiving datagram packets for all players.

In this case, all players send their datagram packets to a single receiver which then decides what to do with the data. This data may be sent to various queues for other threads for processing. Data can be sent back to all players using a single thread or multiple threads (per player).

PROS:

  • Low resource usage
  • Low program (synchronization) overhead.

CONS:

  • Possible network slowness (due to masses of packets going towards the same socket)
  • Higher chance of packet drop (again due to masses of packets going to the same socket)
  • Serial processing
  • Disconnect events are messy and hard to deal with

b) You spawn one thread per player and listen on a different port per player.

In this case, all players get their own handler threads which may process the data directly or send it to a central processing queue. By doing this, data can be processed in parallel, allowing for faster processing speeds with a higher resource usage. Synchronization will also require special attention, uses of atomics and re-entrant read/write locks may be needed. Writing back out to the socket should generally occur on another "per player thread".

PROS:

  • Parallel Processing
  • Modular (have all the handling code per player in one thread, start thread on player join)
  • Disconnects are easier to handle and don't cause problems with other players.
  • Fast network response, concurrent packet receiving.

CONS:

  • High resource usage (a lot more objects)
  • High synchronization overhead
  • High thread count (may be as many as 2 ~ 4x threads to players ratio)

In either case, by using TCP you will need at least one thread per player. The question is are you willing to use a lot more resources for a smoother, swifter response from the server.

initramfs
  • 8,275
  • 2
  • 36
  • 58