# How do multiplayer servers handle receiving, handling, and sending packets?

I want to make a fighter jet simulator game.

The server (authoritative) and client communicate over udp.

The server sends out updates about the gamestate at a fixed rate. Think of plane positions, speeds, rotation, basically anything to do with physics.

On demand, the server sends out packets for spawning bullets and applying damage. So this is not at a fixed tickrate. This is done to sidestep the problem of superbullets and syncing fire rates with tick rates entirely. This class of packets also include chat messages.

How do I go about implementing this? I am using c/c++, programming raw sockets. I am running into the issue where the recvfrom function is blocking. I can set it to non-blocking using fnctl, yes, but that spams error messages because sometimes there are no packets waiting to be handled (I could handle it but egh, inelegant). Ideally I would like to prevent multithreading, but given that there seems to be no native event-driven or interrupt-driven way of receiving packets it seems I need to do that.

How do other game servers, like quake arena, set up their threads?

My idea:

1. Main thread calculates game state, sends out packets at a fixed rate
2. 1 child thread for listening for new packets (recvfrom loop)
• If the incoming packet is a "i am shooting" packet, it performs checks, and broadcasts to every client that a bullet has spawned. It adds the bullet to the world, and the main thread will calculate the continued trajectory in the next or current tickcycle, using the time difference and initial spawn data.
• if the incoming packet is a chat message, perform checks and just broadcast it across clients.
• if the incoming packet is any other kind of packet, put it in a queue for the main thread to handle (the queue is mutexxed)

Is this how I should make the child and main communicate?

• May I suggest reading this document for some background on the potential strategies to attack this problem? kegel.com/c10k.html Oct 13 '20 at 1:33

Everything sounds good except for the fact that you can get client packets in the middle of your state loop, which I think would inevitably create errors and bugs due to concurrent reading/writing on your data. What I propose is having actions and changes. Store the actions in a double-linked list so that you can organize them in the order of their occurrence. The double-linked list is also one of the most performant ways to remove or add actons in Θ(1) time. Then in your loop, you iterate over your double-linked list of actions and produce changes. Now, every iteration you make changes and send them to every client.